DeclTemplate.h revision 686775deca8b8685eb90801495880e3abdd844c2
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;
333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithclass TypeAliasTemplateDecl;
34aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
35f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor/// \brief Stores a template parameter of any kind.
36f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregortypedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
37f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor                            TemplateTemplateParmDecl*> TemplateParameter;
38f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
39aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateParameterList - Stores a list of template parameters for a
40aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateDecl and its derived classes.
41aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList {
42ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The location of the 'template' keyword.
43ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation TemplateLoc;
44ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
45ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The locations of the '<' and '>' angle brackets.
46ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation LAngleLoc, RAngleLoc;
47ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
48ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The number of template parameters in this template
49aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// parameter list.
50aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned NumParams;
51aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
52483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithprotected:
53ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
54bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                        NamedDecl **Params, unsigned NumParams,
55ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
56aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
57aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
584ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateParameterList *Create(const ASTContext &C,
59ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
60ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
61bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                                       NamedDecl **Params,
62ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
63ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
64aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// iterator - Iterates through the template parameters in this list.
66bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl** iterator;
67aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
68aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// const_iterator - Iterates through the template parameters in this list.
69bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl* const* const_iterator;
70aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
71bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
72aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
73bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor    return reinterpret_cast<NamedDecl * const *>(this + 1);
74aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
75aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator end() { return begin() + NumParams; }
76aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator end() const { return begin() + NumParams; }
77aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
78aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned size() const { return NumParams; }
79ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
80bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  NamedDecl* getParam(unsigned Idx) {
81f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
82f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    return begin()[Idx];
83f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  }
84f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
85bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  const NamedDecl* getParam(unsigned Idx) const {
8640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
8740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return begin()[Idx];
8840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
8940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
90910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Returns the minimum number of arguments needed to form a
9162cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template specialization. This may be fewer than the number of
9262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template parameters, if some of the parameters have default
930ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson  /// arguments or if there is a parameter pack.
9462cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  unsigned getMinRequiredArguments() const;
9562cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
96ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Get the depth of this template parameter list in the set of
97ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template parameter lists.
98ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
99ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The first template parameter list in a declaration will have depth 0,
100ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// the second template parameter list will have depth 1, etc.
101ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
102ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
103ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getTemplateLoc() const { return TemplateLoc; }
104ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getLAngleLoc() const { return LAngleLoc; }
105ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getRAngleLoc() const { return RAngleLoc; }
10662cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
10762cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  SourceRange getSourceRange() const {
10862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor    return SourceRange(TemplateLoc, RAngleLoc);
10962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  }
110aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
111aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
112483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith/// FixedSizeTemplateParameterList - Stores a list of template parameters for a
113483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith/// TemplateDecl and its derived classes. Suitable for creating on the stack.
114483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithtemplate<size_t N>
115483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithclass FixedSizeTemplateParameterList : public TemplateParameterList {
116483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  NamedDecl *Params[N];
117483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
118483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithpublic:
119483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  FixedSizeTemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
120483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith                                 NamedDecl **Params, SourceLocation RAngleLoc) :
121483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith    TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) {
122483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  }
123483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith};
124483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
125127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A template argument list.
126127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentList {
127127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template argument list.
128127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
129127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// The integer value will be non-zero to indicate that this
13056ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// template argument list does own the pointer.
131910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> Arguments;
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
133127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in this template
134127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument list.
135910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  unsigned NumArguments;
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
137885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
138885989109ade7cb4dc493e25da41456c64b3cf6aChris Lattner  void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
139910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
140910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs,
141910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                       bool Owned)
142910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    : Arguments(Args, Owned), NumArguments(NumArgs) { }
143910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
144aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
145910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Type used to indicate that the template argument list itself is a
146910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// stack object. It does not own its template arguments.
147910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  enum OnStackType { OnStack };
148910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
149910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Create a new template argument list that copies the given set of
150910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// template arguments.
151910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  static TemplateArgumentList *CreateCopy(ASTContext &Context,
152910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                          const TemplateArgument *Args,
153910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                          unsigned NumArgs);
154910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
155910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Construct a new, temporary template argument list on the stack.
156910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  ///
157910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// The template argument list does not own the template arguments
158910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// provided.
159910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  explicit TemplateArgumentList(OnStackType,
160910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                const TemplateArgument *Args, unsigned NumArgs)
161910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    : Arguments(Args, false), NumArguments(NumArgs) { }
162910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
163910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Produces a shallow copy of the given template argument list.
164910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  ///
165910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// This operation assumes that the input argument list outlives it.
166910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// This takes the list as a pointer to avoid looking like a copy
167910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// constructor, since this really really isn't safe to use that
168910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// way.
169910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  explicit TemplateArgumentList(const TemplateArgumentList *Other)
170910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    : Arguments(Other->data(), false), NumArguments(Other->size()) { }
1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
172127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument &get(unsigned Idx) const {
174910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    assert(Idx < NumArguments && "Invalid template argument index");
175910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return data()[Idx];
176127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
178127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
179127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
181127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in this
182127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list.
183910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  unsigned size() const { return NumArguments; }
1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
185910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Retrieve a pointer to the template argument list.
186910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  const TemplateArgument *data() const {
187910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return Arguments.getPointer();
188127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
189127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
191127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
192127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Templates
193127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
194aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
195127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
196127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// class, function, etc.). The TemplateDecl class stores the list of template
197127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and a reference to the templated scoped declaration: the
198127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// underlying AST node.
199127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateDecl : public NamedDecl {
200127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
201127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // This is probably never used.
202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name)
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
205d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
206127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with the given name and parameters.
207127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
208127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
209127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
211d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
212127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
213127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
214127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
215127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               NamedDecl *Decl)
216127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
217127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParams(Params) { }
218127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
219127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the list of template parameters
220127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
221127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
222d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
223d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
224127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
225127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
226127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
227aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
22880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateDecl *D) { return true; }
2309eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const RedeclarableTemplateDecl *D) { return true; }
231127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D) { return true; }
232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const ClassTemplateDecl *D) { return true; }
233aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
2343e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classof(const TypeAliasTemplateDecl *D) { return true; }
23580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
2369a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstTemplate && K <= lastTemplate;
23780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  }
238aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
23980484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor  SourceRange getSourceRange() const {
24080484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor    return SourceRange(TemplateParams->getTemplateLoc(),
24180484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor                       TemplatedDecl->getSourceRange().getEnd());
24280484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor  }
24380484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor
244127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
245127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
246127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
2478731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
2488731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidispublic:
2498731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Initialize the underlying templated declaration and
2508731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// template parameters.
2518731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
2528731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
2538731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplateParams == 0 && "TemplateParams already set!");
2548731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplatedDecl = templatedDecl;
2558731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplateParams = templateParams;
2568731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  }
257127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Provides information about a function template specialization,
260127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
261127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
262127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
263a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  FunctionTemplateSpecializationInfo(FunctionDecl *FD,
264a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     FunctionTemplateDecl *Template,
265a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     TemplateSpecializationKind TSK,
266a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     const TemplateArgumentList *TemplateArgs,
267a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                          const TemplateArgumentListInfo *TemplateArgsAsWritten,
268a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     SourceLocation POI)
269a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  : Function(FD),
270a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    Template(Template, TSK - 1),
271a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArguments(TemplateArgs),
272a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArgumentsAsWritten(TemplateArgsAsWritten),
273a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    PointOfInstantiation(POI) { }
274a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
275127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
276a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  static FunctionTemplateSpecializationInfo *
277a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
278a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         TemplateSpecializationKind TSK,
279a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentList *TemplateArgs,
280a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentListInfo *TemplateArgsAsWritten,
281a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         SourceLocation POI) {
282a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
283a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                                      TemplateArgs,
284a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                                      TemplateArgsAsWritten,
285a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                                      POI);
286a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  }
287a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
2881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template specialization that this structure
289127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
290127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template from which this function template
293127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
2941fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
295d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
296d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
298127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
299127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
300127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
302e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara  /// \brief The template arguments as written in the sources, if provided.
303e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara  const TemplateArgumentListInfo *TemplateArgumentsAsWritten;
304e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara
305b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief The point at which this function template specialization was
306b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// first instantiated.
307b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
308b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
3091fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
3101fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
311d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
312d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Determine what kind of template specialization this is.
313d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
314d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    return (TemplateSpecializationKind)(Template.getInt() + 1);
315d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  }
316d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
3176ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  bool isExplicitSpecialization() const {
3186ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
3196ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  }
3206ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall
321d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Set the template specialization kind.
322d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(TSK != TSK_Undeclared &&
324d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor         "Cannot encode TSK_Undeclared for a function template specialization");
325d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    Template.setInt(TSK - 1);
3261fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
328b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this function
329b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// template specialization.
330b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  ///
331b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// The point of instantiation may be an invalid source location if this
332b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// function has yet to be instantiated.
333b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation getPointOfInstantiation() const {
334b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    return PointOfInstantiation;
335b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
336b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
337b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the (first) point of instantiation of this function template
338b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// specialization.
339b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
340b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
341b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
342b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
343127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
344910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    Profile(ID, TemplateArguments->data(),
345910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor            TemplateArguments->size(),
3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Function->getASTContext());
347127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
3501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
351828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
352127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
353127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
354828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
3551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
356127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3582db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// \brief Provides information a specialization of a member of a class
3592db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// template, which may be a member function, static data member, or
3602db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor/// member class.
3612db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorclass MemberSpecializationInfo {
36244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // The member declaration from which this member was instantiated, and the
36344e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // manner in which the instantiation occurred (in the lower two bits).
36444e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
3652db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
366b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  // The point at which this member was first instantiated.
367b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
368b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
3692db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorpublic:
3702db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  explicit
3719421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
3729421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis                           SourceLocation POI = SourceLocation())
3739421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
37444e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    assert(TSK != TSK_Undeclared &&
37544e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
37644e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  }
3772db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
3782db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Retrieve the member declaration from which this member was
3792db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// instantiated.
38044e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
3812db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
3822db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Determine what kind of template specialization this is.
3832db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
38444e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
3852db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
3862db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
3872db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Set the template specialization kind.
3882db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
38944e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    assert(TSK != TSK_Undeclared &&
39044e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
39144e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    MemberAndTSK.setInt(TSK - 1);
3922db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
393b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
394b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this member.
395b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// If the point of instantiation is an invalid location, then this member
396b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// has not yet been instantiated.
397b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation getPointOfInstantiation() const {
398b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    return PointOfInstantiation;
399b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
400b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor
401b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the first point of instantiation.
402b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
403b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
404b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
4052db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor};
406af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
407af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// \brief Provides information about a dependent function-template
408af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// specialization declaration.  Since explicit function template
409af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// specialization and instantiation declarations can only appear in
410af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// namespace scope, and you can only specialize a member of a
411af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// fully-specialized class, the only way to get one of these is in
412af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// a friend declaration like the following:
413af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///
414af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   template <class T> void foo(T);
415af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   template <class T> class A {
416af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///     friend void foo<>(T);
417af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   };
418af2094e7cecadf36667deb61a83587ffdd979bd3John McCallclass DependentFunctionTemplateSpecializationInfo {
419af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  union {
420af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // Force sizeof to be a multiple of sizeof(void*) so that the
421af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // trailing data is aligned.
422af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    void *Aligner;
423af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
424af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    struct {
425af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      /// The number of potential template candidates.
426af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      unsigned NumTemplates;
427af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
428af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      /// The number of template arguments.
429af2094e7cecadf36667deb61a83587ffdd979bd3John McCall      unsigned NumArgs;
430af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    } d;
431af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  };
432af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
433af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// The locations of the left and right angle brackets.
434af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceRange AngleLocs;
435af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
436af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl * const *getTemplates() const {
437af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
438af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
439af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
440af2094e7cecadf36667deb61a83587ffdd979bd3John McCallpublic:
441af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  DependentFunctionTemplateSpecializationInfo(
442af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const UnresolvedSetImpl &Templates,
443af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const TemplateArgumentListInfo &TemplateArgs);
444af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
445af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of function templates that this might
446af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// be a specialization of.
447af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplates() const {
448af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumTemplates;
449af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
450af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
451af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the i'th template candidate.
452af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl *getTemplate(unsigned I) const {
453af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplates() && "template index out of range");
454af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplates()[I];
455af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
456af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
457e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  /// \brief Returns the explicit template arguments that were given.
458e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  const TemplateArgumentLoc *getTemplateArgs() const {
459e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor    return reinterpret_cast<const TemplateArgumentLoc*>(
460e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor                                                        &getTemplates()[getNumTemplates()]);
461e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  }
462e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor
463af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of explicit template arguments that were given.
464af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplateArgs() const {
465af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumArgs;
466af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
467af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
468af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the nth template argument.
469af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
470af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplateArgs() && "template arg index out of range");
471af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplateArgs()[I];
472af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
473af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
474af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getLAngleLoc() const {
475af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getBegin();
476af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
477af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
478af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getRAngleLoc() const {
479af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getEnd();
480af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
481af2094e7cecadf36667deb61a83587ffdd979bd3John McCall};
4822db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor
4839eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a redeclarable template.
4849eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass RedeclarableTemplateDecl : public TemplateDecl {
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4869eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getPreviousDeclarationImpl() {
4879eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return CommonOrPrev.dyn_cast<RedeclarableTemplateDecl*>();
4889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
4899eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
4909eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getCanonicalDeclImpl();
4919eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
4928a798a7f7d88dc9865fad7da648e5cef8580c65aPeter Collingbourne  void setPreviousDeclarationImpl(RedeclarableTemplateDecl *Prev);
4939eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
4949eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplateImpl() {
4959eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCommonPtr()->InstantiatedFromMember.getPointer();
4969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
4979eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
4989eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setInstantiatedFromMemberTemplateImpl(RedeclarableTemplateDecl *TD) {
4999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
5009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    getCommonPtr()->InstantiatedFromMember.setPointer(TD);
5019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
5021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
50444dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  template <typename EntryType> struct SpecEntryTraits {
50544dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    typedef EntryType DeclType;
50644dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
50744dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    static DeclType *getMostRecentDeclaration(EntryType *D) {
50844dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne      return D->getMostRecentDeclaration();
50944dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    }
51044dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  };
51144dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
5129f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType,
5139f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _SETraits = SpecEntryTraits<EntryType>,
5149f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _DeclType = typename _SETraits::DeclType>
5159f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  class SpecIterator : public std::iterator<std::forward_iterator_tag,
5169f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, ptrdiff_t,
5179f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, _DeclType*> {
5189f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _SETraits SETraits;
5199f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _DeclType DeclType;
5209f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5219f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef typename llvm::FoldingSet<EntryType>::iterator SetIteratorType;
5229f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5239f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SetIteratorType SetIter;
5249f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5259f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  public:
5269f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator() : SetIter() {}
5279f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
5289f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5299f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator*() const {
5309f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SETraits::getMostRecentDeclaration(&*SetIter);
5319f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5329f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator->() const { return **this; }
5339f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5349f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator &operator++() { ++SetIter; return *this; }
5359f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator operator++(int) {
5369f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      SpecIterator tmp(*this);
5379f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      ++(*this);
5389f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return tmp;
5399f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5409f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5419f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator==(SpecIterator Other) const {
5429f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter == Other.SetIter;
5439f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5449f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator!=(SpecIterator Other) const {
5459f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter != Other.SetIter;
5469f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5479f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  };
5489f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5499f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType>
5509f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  SpecIterator<EntryType> makeSpecIterator(llvm::FoldingSet<EntryType> &Specs,
5519f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                           bool isEnd) {
5529f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
5539f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
5549f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5554048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne  template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
5564048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne  findSpecializationImpl(llvm::FoldingSet<EntryType> &Specs,
5574048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne                         const TemplateArgument *Args, unsigned NumArgs,
5584048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne                         void *&InsertPos);
5594048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne
5609eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct CommonBase {
5619eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    CommonBase() : InstantiatedFromMember(0, false) { }
5629eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
5639eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// \brief The template from which this was most
564d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// directly instantiated (or null).
565fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    ///
5669eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// The boolean value indicates whether this template
567fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// was explicitly specialized.
5689eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
5699eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne      InstantiatedFromMember;
5708a798a7f7d88dc9865fad7da648e5cef8580c65aPeter Collingbourne
5718a798a7f7d88dc9865fad7da648e5cef8580c65aPeter Collingbourne    /// \brief The latest declaration of this template.
5728a798a7f7d88dc9865fad7da648e5cef8580c65aPeter Collingbourne    RedeclarableTemplateDecl *Latest;
5733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
5741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
575127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief A pointer to the previous declaration (if this is a redeclaration)
5769eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// or to the data that is common to all declarations of this template.
5779eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  llvm::PointerUnion<CommonBase*, RedeclarableTemplateDecl*> CommonOrPrev;
5781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5799eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
5809eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// the same template. Calling this routine may implicitly allocate memory
5819eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// for the common pointer.
5829eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  CommonBase *getCommonPtr();
5831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
584da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor  virtual CommonBase *newCommon(ASTContext &C) = 0;
5852c853e401ca406d417eb916e867226050e7be06bArgyrios Kyrtzidis
5869eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  // Construct a template decl with name, parameters, and templated element.
5879eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
5889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                           DeclarationName Name, TemplateParameterList *Params,
5899eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                           NamedDecl *Decl)
5909eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : TemplateDecl(DK, DC, L, Name, Params, Decl),
5919eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne      CommonOrPrev((CommonBase*)0) { }
5921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
5949eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  template <class decl_type> friend class RedeclarableTemplate;
5959eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
5969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getCanonicalDecl() {
5979eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCanonicalDeclImpl();
5983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
6009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this template, or
6019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
6029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getPreviousDeclaration() {
6039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getPreviousDeclarationImpl();
6049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6069eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this template, or
6079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
6089eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const RedeclarableTemplateDecl *getPreviousDeclaration() const {
6099eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return
6109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne      const_cast<RedeclarableTemplateDecl*>(this)->getPreviousDeclaration();
6119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6129eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
613ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// \brief Retrieve the first declaration of this template, or itself
614ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// if this the first one.
615ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  RedeclarableTemplateDecl *getFirstDeclaration() {
616ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis    return getCanonicalDecl();
617ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
618ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
619ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// \brief Retrieve the first declaration of this template, or itself
620ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// if this the first one.
621ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  const RedeclarableTemplateDecl *getFirstDeclaration() const {
622ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis    return
623ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis      const_cast<RedeclarableTemplateDecl*>(this)->getFirstDeclaration();
624ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
625ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
626ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// \brief Retrieve the most recent declaration of this template, or itself
627ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// if this the most recent one.
628ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  RedeclarableTemplateDecl *getMostRecentDeclaration() {
629ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis    return getCommonPtr()->Latest;
630ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
631ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
632ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// \brief Retrieve the most recent declaration of this template, or itself
633ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  /// if this the most recent one.
634ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  const RedeclarableTemplateDecl *getMostRecentDeclaration() const {
635ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis    return
636ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis      const_cast<RedeclarableTemplateDecl*>(this)->getMostRecentDeclaration();
637ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
638ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
6399eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Determines whether this template was a specialization of a
6409eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// member template.
6419eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// In the following example, the function template \c X<int>::f and the
6439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// member template \c X<int>::Inner are member specializations.
6449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \code
6469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<typename T>
6479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// struct X {
6489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template<typename U> void f(T, U);
6499eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template<typename U> struct Inner;
6509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// };
6519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6529eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<> template<typename T>
6539eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// void X<int>::f(int, T);
6549eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<> template<typename T>
6559eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// struct X<int>::Inner { /* ... */ };
6569eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \endcode
6579eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  bool isMemberSpecialization() {
6589eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCommonPtr()->InstantiatedFromMember.getInt();
6599eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6609eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
6619eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Note that this member template is a specialization.
6629eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setMemberSpecialization() {
6639eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
6649eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne           "Only member templates can be member template specializations");
6659eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    getCommonPtr()->InstantiatedFromMember.setInt(true);
6669eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6679eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
6689eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this template, or
6699eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
6709eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() {
6719eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getInstantiatedFromMemberTemplateImpl();
6729eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6739eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
674da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor  virtual RedeclarableTemplateDecl *getNextRedeclaration();
675f88718ea0ca0d64b7fd31d109f1d9ec769a9c45fPeter Collingbourne
6769eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  // Implement isa/cast/dyncast/etc.
6779eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
6789eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const RedeclarableTemplateDecl *D) { return true; }
6799eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const FunctionTemplateDecl *D) { return true; }
6809eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const ClassTemplateDecl *D) { return true; }
6813e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classof(const TypeAliasTemplateDecl *D) { return true; }
6829eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classofKind(Kind K) {
6839eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
6849eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6859eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
686d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
6873397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
6889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne};
6899eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
6909eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbournetemplate <class decl_type>
6919eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass RedeclarableTemplate {
6929eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl *thisDecl() {
6939eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<decl_type*>(this);
6949eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
6959eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
6969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbournepublic:
697127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
698127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
6999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  decl_type *getPreviousDeclaration() {
7009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<decl_type*>(thisDecl()->getPreviousDeclarationImpl());
7013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
7023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
703127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
704127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
7059eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const decl_type *getPreviousDeclaration() const {
7069eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return const_cast<RedeclarableTemplate*>(this)->getPreviousDeclaration();
7073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
7081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
709127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the previous declaration of this function template.
7109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setPreviousDeclaration(decl_type *Prev) {
7119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    thisDecl()->setPreviousDeclarationImpl(Prev);
7129eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7139eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  decl_type *getCanonicalDecl() {
7159eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<decl_type*>(thisDecl()->getCanonicalDeclImpl());
716127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
7171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const decl_type *getCanonicalDecl() const {
7199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return const_cast<RedeclarableTemplate*>(this)->getCanonicalDecl();
7209eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7229eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the member template that this template was instantiated
7239eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// from.
724d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
7259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// This routine will return non-NULL for member templates of
726d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// class templates.  For example, given:
727d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
728d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \code
729d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template <typename T>
730d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// struct X {
731d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///   template <typename U> void f();
7329eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template <typename U> struct A {};
733d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// };
734d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \endcode
735d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
7369eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// X<int>::f<float> is a CXXMethodDecl (whose parent is X<int>, a
7371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
738d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
739d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
7401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
741d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// ClassTemplateDecl).
742d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
7439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
7449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
7459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// return X<int>::A<U>, a ClassTemplateDecl (whose parent is again
7469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
7479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// X<T>::A<U>, a ClassTemplateDecl (whose parent is X<T>, also a CTD).
7489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
7499eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \returns NULL if this is not an instantiation of a member template.
7509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  decl_type *getInstantiatedFromMemberTemplate() {
7519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<decl_type*>(
7529eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne             thisDecl()->getInstantiatedFromMemberTemplateImpl());
753d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
7541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7559eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setInstantiatedFromMemberTemplate(decl_type *TD) {
7569eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    thisDecl()->setInstantiatedFromMemberTemplateImpl(TD);
757d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
7589eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne};
7591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
76044dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbournetemplate <> struct RedeclarableTemplateDecl::
76144dd0b440efdb37ff4c6e49f243faa3b0580b120Peter CollingbourneSpecEntryTraits<FunctionTemplateSpecializationInfo> {
76244dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  typedef FunctionDecl DeclType;
76344dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
76444dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  static DeclType *
76544dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  getMostRecentDeclaration(FunctionTemplateSpecializationInfo *I) {
76644dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    return I->Function->getMostRecentDeclaration();
76744dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  }
76844dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne};
76944dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
7709eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a template function.
7719eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass FunctionTemplateDecl : public RedeclarableTemplateDecl,
7729eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                             public RedeclarableTemplate<FunctionTemplateDecl> {
7739eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static void DeallocateCommon(void *Ptr);
7749eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7759eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
7769eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  typedef RedeclarableTemplate<FunctionTemplateDecl> redeclarable_base;
7779eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7789eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Data that is common to all of the declarations of a given
7799eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
7809eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
781c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    Common() : InjectedArgs(0) { }
782c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor
7839eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// \brief The function template specializations for this function
7849eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// template, including explicit specializations and instantiations.
7859eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
786c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor
787c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// \brief The set of "injected" template arguments used within this
788c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// function template.
789c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    ///
790c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// This pointer refers to the template arguments (there are as
791c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// many template arguments as template parameaters) for the function
792c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// template, and is allocated lazily, since most function templates do not
793c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// require the use of this information.
794c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    TemplateArgument *InjectedArgs;
7959eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  };
7969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7979eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
7989eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                       TemplateParameterList *Params, NamedDecl *Decl)
7999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
8009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8016b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  CommonBase *newCommon(ASTContext &C);
8029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  Common *getCommonPtr() {
8049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
805fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
8069eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8076b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  friend class FunctionDecl;
808da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor
8099eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the set of function template specializations of this
8109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
8119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
8129eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCommonPtr()->Specializations;
813fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
8145bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl
8155bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  /// \brief Add a specialization of this function template.
8165bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  ///
8175bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  /// \param InsertPos Insert position in the FoldingSet, must have been
8185bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  ///        retrieved by an earlier call to findSpecialization().
8195bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  void addSpecialization(FunctionTemplateSpecializationInfo* Info,
8205bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl                         void *InsertPos);
821fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor
8229eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbournepublic:
8239eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// Get the underlying function declaration of the template.
8249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionDecl *getTemplatedDecl() const {
8259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<FunctionDecl*>(TemplatedDecl);
8269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8279eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
82813fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// Returns whether this template declaration defines the primary
82913fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// pattern.
83013fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
83113fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
83213fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
83313fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
8349eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Return the specialization with the provided arguments if it exists,
8359eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// otherwise return the insertion point.
8369eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionDecl *findSpecialization(const TemplateArgument *Args,
8379eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                                   unsigned NumArgs, void *&InsertPos);
8389eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8399eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getCanonicalDecl() {
8409eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getCanonicalDecl();
8419eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const FunctionTemplateDecl *getCanonicalDecl() const {
8439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getCanonicalDecl();
8449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this function template, or
8479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
8489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getPreviousDeclaration() {
8499eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getPreviousDeclaration();
8509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8529eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this function template, or
8539eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
8549eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const FunctionTemplateDecl *getPreviousDeclaration() const {
8559eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getPreviousDeclaration();
8569eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8579eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8589eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
8599eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getInstantiatedFromMemberTemplate();
8609eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8619eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8629f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
8639f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
8649f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  spec_iterator spec_begin() {
8659f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
8669f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8679f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
8689f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  spec_iterator spec_end() {
8699f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
8709f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8719f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
872c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// \brief Retrieve the "injected" template arguments that correspond to the
873c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// template parameters of this function template.
874c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  ///
875c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// Although the C++ standard has no notion of the "injected" template
876c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// arguments for a function template, the notion is convenient when
877c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// we need to perform substitutions inside the definition of a function
878c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// template.
879c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  std::pair<const TemplateArgument *, unsigned> getInjectedTemplateArgs();
880c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor
8819a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  /// \brief Create a function template node.
882127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
883127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
884127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
885127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
886127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
8873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
8889a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  /// \brief Create an empty function template node.
8899a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, EmptyShell);
8909a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
891127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
89280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
89380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const FunctionTemplateDecl *D) { return true; }
89480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == FunctionTemplate; }
895c8f9af2943699ff623ca08f2e5ed4d72e0351189Argyrios Kyrtzidis
896d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
8973397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
898127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
899d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
900127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
901127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
902127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
90340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
904127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
905127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// within a template parameter list. Because template parameter can be listed
906127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
907127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
908127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
909127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
910127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
9111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass TemplateParmPosition {
912127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
913127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
914127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
915127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
916127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
9173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
918127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
919127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
920127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
9213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
922127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
923127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
924127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
925127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
9263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
927127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
928127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
929127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
930b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setDepth(unsigned D) { Depth = D; }
9313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
932127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
933127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
934b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setPosition(unsigned P) { Position = P; }
9351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
936127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
937127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
938127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
9393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
940127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
941127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
942127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
943127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
944127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
945127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
946127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
947127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
948127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// 'class' keyword.
949127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
9503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
951127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
952127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
953127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
9543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
955127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
956a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *DefaultArgument;
957127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
958344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara  TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
959344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                       SourceLocation IdLoc, IdentifierInfo *Id,
9604fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth                       bool Typename)
961344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara    : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
9624fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth      InheritedDefault(false), DefaultArgument() { }
9633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
964483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  /// Sema creates these on the stack during auto type deduction.
965483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  friend class Sema;
966483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
967127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
9684ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
969344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      SourceLocation KeyLoc,
970344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      SourceLocation NameLoc,
971344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      unsigned D, unsigned P,
972127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
973127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
9744ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateTypeParmDecl *Create(const ASTContext &C, EmptyShell Empty);
975c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
976127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
977127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
978127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// keyword.
979127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
980c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
981127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
982127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
983833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  bool hasDefaultArgument() const { return DefaultArgument != 0; }
984199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
985127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
986833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
98740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
988833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the default argument's source information, if any.
989a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
990833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
991833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the location of the default argument declaration.
992833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  SourceLocation getDefaultArgumentLoc() const;
99340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
994127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
995127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
996127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
997f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
998127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
999127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
1000127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
1001a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
1002127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
1003127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
1004f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
100540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
1006833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Removes the default argument of this template parameter.
1007833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  void removeDefaultArgument() {
1008833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    DefaultArgument = 0;
1009833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    InheritedDefault = false;
1010833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
10118731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
10128731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Set whether this template type parameter was declared with
10138731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// the 'typename' or 'class' keyword.
10148731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
10158731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
1016ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the depth of the template parameter.
1017ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
1018ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1019ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the index of the template parameter.
1020ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getIndex() const;
1021ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1022127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
10234fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth  bool isParameterPack() const;
1024fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
102577d4ee2bfc90b77ec8b818de985cd4aceeef757bAbramo Bagnara  SourceRange getSourceRange() const;
102677d4ee2bfc90b77ec8b818de985cd4aceeef757bAbramo Bagnara
1027127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
102880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1029127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
103080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
10313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
10323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1033127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1034127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
1035127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1036127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
1037127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1038127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
103976a40219ee5624d78aba167dce02bdbaa930955fJohn McCall  : public DeclaratorDecl, protected TemplateParmPosition {
1040d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief The default template argument, if any, and whether or not
1041d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// it was inherited.
1042d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
1043127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
104410738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
104510738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  // down here to save memory.
104610738d36b150aa65206890c1c845cdba076e4200Douglas Gregor
104710738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \brief Whether this non-type template parameter is a parameter pack.
104810738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  bool ParameterPack;
104910738d36b150aa65206890c1c845cdba076e4200Douglas Gregor
10506952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief Whether this non-type template parameter is an "expanded"
10516952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// parameter pack, meaning that its type is a pack expansion and we
10526952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// already know the set of types that expansion expands to.
10536952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  bool ExpandedParameterPack;
10546952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
10556952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief The number of types in an expanded parameter pack.
10566952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  unsigned NumExpandedTypes;
10576952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1058ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1059ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          SourceLocation IdLoc, unsigned D, unsigned P,
1060ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          IdentifierInfo *Id, QualType T,
106110738d36b150aa65206890c1c845cdba076e4200Douglas Gregor                          bool ParameterPack, TypeSourceInfo *TInfo)
1062ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
106310738d36b150aa65206890c1c845cdba076e4200Douglas Gregor      TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
10646952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      ParameterPack(ParameterPack), ExpandedParameterPack(false),
10656952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      NumExpandedTypes(0)
1066127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
1067127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1068ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1069ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          SourceLocation IdLoc, unsigned D, unsigned P,
1070ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          IdentifierInfo *Id, QualType T,
10716952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          TypeSourceInfo *TInfo,
10726952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          const QualType *ExpandedTypes,
10736952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          unsigned NumExpandedTypes,
10746952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          TypeSourceInfo **ExpandedTInfos);
10756952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
107610738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  friend class ASTDeclReader;
107710738d36b150aa65206890c1c845cdba076e4200Douglas Gregor
10781c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
1079127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
1080ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1081ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1082ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
10839ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
10846952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  static NonTypeTemplateParmDecl *
1085ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1086ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1087ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         QualType T, TypeSourceInfo *TInfo,
10886952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor         const QualType *ExpandedTypes, unsigned NumExpandedTypes,
10896952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor         TypeSourceInfo **ExpandedTInfos);
10906952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1091127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1092b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setDepth;
1093127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1094b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setPosition;
1095127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
10961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
109776a40219ee5624d78aba167dce02bdbaa930955fJohn McCall  SourceRange getSourceRange() const;
109876a40219ee5624d78aba167dce02bdbaa930955fJohn McCall
1099127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1100127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1101d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
1102d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer() != 0;
1103d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1104fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
1105127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1106d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  Expr *getDefaultArgument() const {
1107d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer();
1108d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1109127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1110127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
1111127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
1112127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1113d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1114d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1115d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1116d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getInt();
1117d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1118d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1119d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1120d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1121d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1122d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(Expr *DefArg, bool Inherited) {
1123d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(DefArg);
1124d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(Inherited);
1125d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1126d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1127d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1128d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
1129d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(0);
1130d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(false);
11313b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
1132127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
113310738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \brief Whether this parameter is a non-type template parameter pack.
113410738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  ///
113510738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// If the parameter is a parameter pack, the type may be a
113610738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \c PackExpansionType. In the following example, the \c Dims parameter
113710738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// is a parameter pack (whose type is 'unsigned').
113810738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  ///
113910738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \code
114010738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// template<typename T, unsigned ...Dims> struct multi_array;
114110738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \endcode
114210738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  bool isParameterPack() const { return ParameterPack; }
114310738d36b150aa65206890c1c845cdba076e4200Douglas Gregor
11446952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief Whether this parameter is a non-type template parameter pack
11456952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// that has different types at different positions.
11466952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11476952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// A parameter pack is an expanded parameter pack when the original
11486952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// parameter pack's type was itself a pack expansion, and that expansion
11496952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// has already been expanded. For example, given:
11506952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11516952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \code
11526952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// template<typename ...Types>
11536952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// struct X {
11546952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///   template<Types ...Values>
11556952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///   struct Y { /* ... */ };
11566952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// };
11576952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \endcode
11586952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11596952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// The parameter pack \c Values has a \c PackExpansionType as its type,
11606952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// which expands \c Types. When \c Types is supplied with template arguments
11616952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// by instantiating \c X, the instantiation of \c Values becomes an
11626952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// expanded parameter pack. For example, instantiating
11636952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \c X<int, unsigned int> results in \c Values being an expanded parameter
11646952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// pack with expansion types \c int and \c unsigned int.
11656952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11666952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
11676952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// return the expansion types.
11686952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
11696952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
11706952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief Retrieves the number of expansion types in an expanded parameter pack.
11716952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  unsigned getNumExpansionTypes() const {
11726952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(ExpandedParameterPack && "Not an expansion parameter pack");
11736952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return NumExpandedTypes;
11746952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11756952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
11766952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief Retrieve a particular expansion type within an expanded parameter
11776952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// pack.
11786952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  QualType getExpansionType(unsigned I) const {
11796952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
11806952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
11816952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return QualType::getFromOpaquePtr(TypesAndInfos[2*I]);
11826952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11836952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
11846952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief Retrieve a particular expansion type source info within an
11856952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// expanded parameter pack.
11866952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
11876952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
11886952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
11896952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]);
11906952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11916952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1192127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
119380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1194127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
119580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
11961c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
11971c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
1198127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
1199127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
1200127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1201127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
1202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
1204127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
1205127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTemplateParmDecl
1206127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
12077e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1208d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// DefaultArgument - The default template argument, if any.
1209788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  TemplateArgumentLoc DefaultArgument;
1210d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// Whether or not the default argument was inherited.
1211d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool DefaultArgumentWasInherited;
12127e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
121361c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  /// \brief Whether this parameter is a parameter pack.
121461c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  bool ParameterPack;
121561c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor
1216127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
121761c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                           unsigned D, unsigned P, bool ParameterPack,
1218127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
1219127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1220d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      TemplateParmPosition(D, P), DefaultArgument(),
122161c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor      DefaultArgumentWasInherited(false), ParameterPack(ParameterPack)
1222127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
12237e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1224127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
12254ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
1226127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
122761c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                                          unsigned P, bool ParameterPack,
122861c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                                          IdentifierInfo *Id,
1229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
12307e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1231127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
12341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1235d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \brief Whether this template template parameter is a template
1236d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// parameter pack.
1237d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  ///
1238d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \code
1239d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// template<template <class T> ...MetaFunctions> struct Apply;
1240d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \endcode
124161c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  bool isParameterPack() const { return ParameterPack; }
1242d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
1243127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1244127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1245d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
1246d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return !DefaultArgument.getArgument().isNull();
1247788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
12487e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1249127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1250d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  const TemplateArgumentLoc &getDefaultArgument() const {
1251d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgument;
1252d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1253d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1254d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Retrieve the location of the default argument, if any.
1255d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  SourceLocation getDefaultArgumentLoc() const;
1256d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1257d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1258d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1259d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1260d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentWasInherited;
1261788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
12627e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1263d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1264d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1265d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1266d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
1267127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
1268d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = Inherited;
1269d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1270d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1271d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1272d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
1273d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgument = TemplateArgumentLoc();
1274d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = false;
1275127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
12767e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1277fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  SourceRange getSourceRange() const {
1278fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    SourceLocation End = getLocation();
1279fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (hasDefaultArgument() && !defaultArgumentWasInherited())
1280fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      End = getDefaultArgument().getSourceRange().getEnd();
1281fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1282fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  }
1283fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1284127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
128580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1286127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
128780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1288bfcc92c3476ada55ceeea49e43e6d2e083252830Argyrios Kyrtzidis
1289d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
12903397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
12917e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
12927e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
12933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
12943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
12953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
12963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
12973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
12983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
12993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
13003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
13013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
13021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
13031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// template<>
13043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
13053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
13061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplateSpecializationDecl
13073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
13081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Structure that stores information about a class template
131037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
131137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
131237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
131337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
131437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
131537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
13161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
131737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
131837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
131937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    TemplateArgumentList *TemplateArgs;
132037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
13211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
132337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
132437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
13253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1326c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
1327c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  struct ExplicitSpecializationInfo {
1328c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The type-as-written.
1329c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    TypeSourceInfo *TypeAsWritten;
1330c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the extern keyword.
1331c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation ExternLoc;
1332c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the template keyword.
1333c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation TemplateKeywordLoc;
1334c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1335c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitSpecializationInfo()
1336c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara      : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
1337c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  };
1338c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1339c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
13403cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// Does not apply to implicit specializations.
1341c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  ExplicitSpecializationInfo *ExplicitInfo;
13423cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
13437e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
1344910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  TemplateArgumentList *TemplateArgs;
1345cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
13469cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief The point where this template was instantiated (if any)
13479cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation PointOfInstantiation;
13489cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
1349cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
1350cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
1351d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  unsigned SpecializationKind : 3;
1352cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1353c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
135413c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
1355ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                  DeclContext *DC, SourceLocation StartLoc,
1356ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                  SourceLocation IdLoc,
13573e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
1358910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                  const TemplateArgument *Args,
1359910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                  unsigned NumArgs,
13608e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
13611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
136294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  explicit ClassTemplateSpecializationDecl(Kind DK);
136394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
13643e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
13653e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
1366ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1367ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara         SourceLocation StartLoc, SourceLocation IdLoc,
13683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
1369910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         const TemplateArgument *Args,
1370910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         unsigned NumArgs,
1371cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
1372b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  static ClassTemplateSpecializationDecl *
1373b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  Create(ASTContext &Context, EmptyShell Empty);
137494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1375da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor  virtual void getNameForDiagnostic(std::string &S,
1376da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor                                    const PrintingPolicy &Policy,
1377da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor                                    bool Qualified) const;
1378da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor
1379cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplateSpecializationDecl *getMostRecentDeclaration() {
1380cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    CXXRecordDecl *Recent
1381cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis        = cast<CXXRecordDecl>(CXXRecordDecl::getMostRecentDeclaration());
1382cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    if (!isa<ClassTemplateSpecializationDecl>(Recent)) {
1383cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis      // FIXME: Does injected class name need to be in the redeclarations chain?
1384cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis      assert(Recent->isInjectedClassName() && Recent->getPreviousDeclaration());
1385cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis      Recent = Recent->getPreviousDeclaration();
1386cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    }
1387cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplateSpecializationDecl>(Recent);
1388cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1389cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
13903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
139137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
13923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
13931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the template arguments of the class template
139437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
13951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgumentList &getTemplateArgs() const {
1396910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return *TemplateArgs;
13973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
13983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1399cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
1400cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
1401cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
1402cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
1403cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1404cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
14056ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  bool isExplicitSpecialization() const {
14066ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall    return getSpecializationKind() == TSK_ExplicitSpecialization;
14076ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  }
14086ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall
1409cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
1410cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
1411cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1412cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
14139cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief Get the point of instantiation (if any), or null if none.
14149cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation getPointOfInstantiation() const {
14159cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    return PointOfInstantiation;
14169cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
14179cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
14189cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  void setPointOfInstantiation(SourceLocation Loc) {
14199cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    assert(Loc.isValid() && "point of instantiation must be valid!");
14209cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    PointOfInstantiation = Loc;
14219cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
14229cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
142337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
142437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
142537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
142637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
14271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::PointerUnion<ClassTemplateDecl *,
142837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
142937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
143037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
1431d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
1432d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
1433e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor      return llvm::PointerUnion<ClassTemplateDecl *,
1434e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor                                ClassTemplatePartialSpecializationDecl *>();
14351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
143737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
143837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
14391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
144037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return const_cast<ClassTemplateDecl*>(
144137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                             SpecializedTemplate.get<ClassTemplateDecl*>());
144237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
14431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
144494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Retrieve the class template or class template partial
144594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// specialization which was specialized by this.
144694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  llvm::PointerUnion<ClassTemplateDecl *,
144794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis                     ClassTemplatePartialSpecializationDecl *>
144894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  getSpecializedTemplateOrPartial() const {
144994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    if (SpecializedPartialSpecialization *PartialSpec
145094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
145194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      return PartialSpec->PartialSpecialization;
145294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
145394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    return const_cast<ClassTemplateDecl*>(
145494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis                             SpecializedTemplate.get<ClassTemplateDecl*>());
145594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
145694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
145737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
145837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
145937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
146037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
146137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
146237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
146337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
146437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
146537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
146637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
146737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
146837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
14691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
147037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
147137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
14721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
147337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
147437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
14751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
147637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
147737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
147837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
147937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
148037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                          TemplateArgumentList *TemplateArgs) {
148194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
148294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Already set to a class template partial specialization!");
14831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SpecializedPartialSpecialization *PS
148437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
148537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
148637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
148737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
148837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
14891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
149094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Note that this class template specialization is an instantiation
149194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// of the given class template.
149294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
149394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
149494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Previously set to a class template partial specialization!");
149594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    SpecializedTemplate = TemplDecl;
149694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
149794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1498fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
1499fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
15003cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  void setTypeAsWritten(TypeSourceInfo *T) {
1501db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1502db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1503c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TypeAsWritten = T;
15043cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  }
15053cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Gets the type of this specialization as it was written by
15063cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// the user, if it was so written.
15073cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  TypeSourceInfo *getTypeAsWritten() const {
1508c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
1509c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1510c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1511c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the extern keyword, if present.
1512c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getExternLoc() const {
1513c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
1514c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1515c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the extern keyword.
1516c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setExternLoc(SourceLocation Loc) {
1517db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1518db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1519c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->ExternLoc = Loc;
1520c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1521c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1522c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the template keyword.
1523c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setTemplateKeywordLoc(SourceLocation Loc) {
1524db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1525db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1526c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TemplateKeywordLoc = Loc;
1527c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1528c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the template keyword, if present.
1529c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getTemplateKeywordLoc() const {
1530c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
1531fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
1532fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
15334a85a73466bfb541cd9c7b57a99292a0b6900b9bAbramo Bagnara  SourceRange getSourceRange() const;
15344a85a73466bfb541cd9c7b57a99292a0b6900b9bAbramo Bagnara
1535c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1536910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
1537c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1538c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
15391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
15401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
1541828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
15420ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
15433e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
1544828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
15453e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
15463e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
154780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
154880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
15499a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstClassTemplateSpecialization &&
15509a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt           K <= lastClassTemplateSpecialization;
15513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
15523e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
15533e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateSpecializationDecl *) {
15543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return true;
15553e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
1556c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1557c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1558c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1559c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1560586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis
1561586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclReader;
1562586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclWriter;
1563c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1564c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
15651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplatePartialSpecializationDecl
15661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public ClassTemplateSpecializationDecl {
15671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The list of template parameters
1568c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1569c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1570833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief The source info for the template arguments as written.
15713cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// FIXME: redundant with TypeAsWritten?
1572833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc *ArgsAsWritten;
1573833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  unsigned NumArgsAsWritten;
1574833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1575dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Sequence number indicating when this class template partial
1576dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// specialization was added to the set of partial specializations for
1577dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// its owning class template.
1578dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  unsigned SequenceNumber;
1579dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor
1580ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief The class template partial specialization from which this
1581ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// class template partial specialization was instantiated.
1582ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1583ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The boolean value will be true to indicate that this class template
1584ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// partial specialization was specialized at this level.
1585ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
1586ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      InstantiatedFromMember;
1587ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
158813c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1589ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         DeclContext *DC,
1590ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         SourceLocation StartLoc,
1591ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         SourceLocation IdLoc,
1592c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1593c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
1594910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                         const TemplateArgument *Args,
1595910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                         unsigned NumArgs,
1596833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall                                         TemplateArgumentLoc *ArgInfos,
1597833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall                                         unsigned NumArgInfos,
1598dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor                               ClassTemplatePartialSpecializationDecl *PrevDecl,
15999a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor                                         unsigned SequenceNumber);
160094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
160194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl()
160294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
160394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      TemplateParams(0), ArgsAsWritten(0),
160494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      NumArgsAsWritten(0), SequenceNumber(0),
160594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      InstantiatedFromMember(0, false) { }
1606c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1607c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1608c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
1609ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara  Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1610ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara         SourceLocation StartLoc, SourceLocation IdLoc,
1611c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1612c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
1613910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         const TemplateArgument *Args,
1614910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         unsigned NumArgs,
1615d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall         const TemplateArgumentListInfo &ArgInfos,
16163cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall         QualType CanonInjectedType,
1617dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor         ClassTemplatePartialSpecializationDecl *PrevDecl,
1618dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor         unsigned SequenceNumber);
1619c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
162094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  static ClassTemplatePartialSpecializationDecl *
1621b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  Create(ASTContext &Context, EmptyShell Empty);
162294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1623cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *getMostRecentDeclaration() {
1624cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplatePartialSpecializationDecl>(
1625cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                   ClassTemplateSpecializationDecl::getMostRecentDeclaration());
1626cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1627cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1628c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1629c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1630c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1631c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1632c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1633833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the template arguments as written.
1634833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc *getTemplateArgsAsWritten() const {
1635833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return ArgsAsWritten;
1636833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1637833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1638833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the number of template arguments as written.
1639833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  unsigned getNumTemplateArgsAsWritten() const {
1640833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return NumArgsAsWritten;
1641833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1642833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1643dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Get the sequence number for this class template partial
1644dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// specialization.
1645dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  unsigned getSequenceNumber() const { return SequenceNumber; }
16468fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis
1647ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the member class template partial specialization from
1648ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// which this particular class template partial specialization was
1649ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// instantiated.
1650ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1651ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1652ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1653ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct Outer {
1654ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1655ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*> { }; // #1
1656ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1657ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1658ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// Outer<float>::Inner<int*> ii;
1659ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1660ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1661ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
1662ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// end up instantiating the partial specialization
1663ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
1664ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template partial specialization \c Outer<T>::Inner<U*>. Given
1665ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, this function would return
1666ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<T>::Inner<U*>.
1667ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
1668ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1669ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1670ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getPointer();
1671ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1672ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1673ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setInstantiatedFromMember(
1674ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
1675ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1676ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1677ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    First->InstantiatedFromMember.setPointer(PartialSpec);
1678ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1679ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1680ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Determines whether this class template partial specialization
1681ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template was a specialization of a member partial specialization.
1682ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1683ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In the following example, the member template partial specialization
1684ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c X<int>::Inner<T*> is a member specialization.
1685ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1686ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1687ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1688ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X {
1689ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1690ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*>;
1691ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1692ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1693ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<> template<typename T>
1694ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X<int>::Inner<T*> { /* ... */ };
1695ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1696ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  bool isMemberSpecialization() {
1697ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1698ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1699ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getInt();
1700ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1701ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1702ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Note that this member template is a specialization.
1703ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setMemberSpecialization() {
1704ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1705ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1706ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    assert(First->InstantiatedFromMember.getPointer() &&
1707ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor           "Only member templates can be member template specializations");
1708ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.setInt(true);
1709ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
171031f17ecbef57b5679c017c375db330546b7b5145John McCall
171131f17ecbef57b5679c017c375db330546b7b5145John McCall  /// Retrieves the injected specialization type for this partial
171231f17ecbef57b5679c017c375db330546b7b5145John McCall  /// specialization.  This is not the same as the type-decl-type for
171331f17ecbef57b5679c017c375db330546b7b5145John McCall  /// this partial specialization, which is an InjectedClassNameType.
171431f17ecbef57b5679c017c375db330546b7b5145John McCall  QualType getInjectedSpecializationType() const {
171531f17ecbef57b5679c017c375db330546b7b5145John McCall    assert(getTypeForDecl() && "partial specialization has no type set!");
171631f17ecbef57b5679c017c375db330546b7b5145John McCall    return cast<InjectedClassNameType>(getTypeForDecl())
171731f17ecbef57b5679c017c375db330546b7b5145John McCall             ->getInjectedSpecializationType();
171831f17ecbef57b5679c017c375db330546b7b5145John McCall  }
1719ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1720c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1721c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
172280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
172380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
172480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall    return K == ClassTemplatePartialSpecialization;
1725c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1726c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1727c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1728c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1729c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
17308fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis
17318fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclReader;
17328fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclWriter;
17333e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
17343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
17353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
17369eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass ClassTemplateDecl : public RedeclarableTemplateDecl,
17379eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                          public RedeclarableTemplate<ClassTemplateDecl> {
17380054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  static void DeallocateCommon(void *Ptr);
17390054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor
17403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
17419eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  typedef RedeclarableTemplate<ClassTemplateDecl> redeclarable_base;
17429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
17435953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
17445953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
17459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
1746c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    Common() : LazySpecializations() { }
1747c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor
17485953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
17495953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
17505953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
17517da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1752c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1753c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
17541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
1755c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1756c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
17577da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
17587da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1759c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor
1760c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// \brief If non-null, points to an array of specializations (including
1761c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// partial specializations) known ownly by their external declaration IDs.
1762c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    ///
1763c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// The first value in the array is the number of of specializations/
1764c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// partial specializations that follow.
1765c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    uint32_t *LazySpecializations;
17665953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
17675953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1768c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  /// \brief Load any lazily-loaded specializations from the external source.
1769c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  void LoadLazySpecializations();
1770c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor
1771cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of specializations of this class template.
1772c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations();
1773cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1774cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of partial specializations of this class
1775cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// template.
1776cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
1777c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  getPartialSpecializations();
1778cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
17793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
17808731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis                    TemplateParameterList *Params, NamedDecl *Decl)
17819eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
17829eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
17839a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  ClassTemplateDecl(EmptyShell Empty)
17849a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor    : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
17859a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor                               DeclarationName(), 0, 0) { }
17869a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
17876b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  CommonBase *newCommon(ASTContext &C);
17889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
17899eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  Common *getCommonPtr() {
17909eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
17919eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
17923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
17933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
17943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Get the underlying class declarations of the template.
17953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
17963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
17973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
17983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
179913fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// Returns whether this template declaration defines the primary
180013fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// class pattern.
180113fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
180213fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
180313fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
180413fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
18055953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// Create a class template node.
18063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
18073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
18083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
18093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
18105953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
18115953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
18123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
18139a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  /// Create an empty class template node.
18149a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, EmptyShell);
18159a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
1816cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the specialization with the provided arguments if it exists,
1817cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// otherwise return the insertion point.
1818cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplateSpecializationDecl *
1819cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1820cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                     void *&InsertPos);
1821cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1822cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified specialization knowing that it is not already
1823cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// in. InsertPos must be obtained from findSpecialization.
1824bef1a7b9c175d37e4a727e6ce68bd05232fa6970Argyrios Kyrtzidis  void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
18253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
18269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getCanonicalDecl() {
18279eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getCanonicalDecl();
18289eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18299eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const ClassTemplateDecl *getCanonicalDecl() const {
18309eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getCanonicalDecl();
18319eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18329eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18339eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
18349eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
18359eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getPreviousDeclaration() {
18369eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getPreviousDeclaration();
18379eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18389eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18399eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
18409eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
18419eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const ClassTemplateDecl *getPreviousDeclaration() const {
18429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getPreviousDeclaration();
18439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
18469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return redeclarable_base::getInstantiatedFromMemberTemplate();
18479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1849cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the partial specialization with the provided arguments if it
1850cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// exists, otherwise return the insertion point.
1851cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1852cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1853cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                            void *&InsertPos);
1854cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1855cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified partial specialization knowing that it is not
1856cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// already in. InsertPos must be obtained from findPartialSpecialization.
1857cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
1858bef1a7b9c175d37e4a727e6ce68bd05232fa6970Argyrios Kyrtzidis                                void *InsertPos);
1859cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1860cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the next partial specialization sequence number.
1861cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  unsigned getNextPartialSpecSequenceNumber() {
1862cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return getPartialSpecializations().size();
1863c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1864c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1865dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Retrieve the partial specializations as an ordered list.
1866dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  void getPartialSpecializations(
1867686775deca8b8685eb90801495880e3abdd844c2Chris Lattner          SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
1868dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor
1869b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1870b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1871b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1872cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param T a dependent type that names a specialization of this class
1873b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1874b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1875b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1876b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1877b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
1878cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1879cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Find a class template partial specialization which was instantiated
1880cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization.
1881cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1882cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param D a member class template partial specialization.
1883cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1884cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \returns the class template partial specialization which was instantiated
1885cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization, or NULL if no such partial
1886cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// specialization exists.
1887cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1888cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findPartialSpecInstantiatedFromMember(
1889cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                                     ClassTemplatePartialSpecializationDecl *D);
18901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18913cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Retrieve the template specialization type of the
18923cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// injected-class-name for this class template.
18937da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
18947da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
18957da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
18967da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
18977da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
18987da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
18997da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
19007da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
19017da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
19027da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
19037da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
19047da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
190524bae92f08ae098cc50a602d8cf1273b423e14daDouglas Gregor  QualType getInjectedClassNameSpecialization();
19067da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
19079f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
19089f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19099f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  spec_iterator spec_begin() {
19109f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
19119f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19129f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19139f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  spec_iterator spec_end() {
19149f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
19159f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19169f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19179f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
19189f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne          partial_spec_iterator;
19199f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19209f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  partial_spec_iterator partial_spec_begin() {
19219f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getPartialSpecializations(), false);
19229f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19239f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19249f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  partial_spec_iterator partial_spec_end() {
19259f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getPartialSpecializations(), true);
19269f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19279f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
192980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
193080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const ClassTemplateDecl *D) { return true; }
193180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ClassTemplate; }
19325953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1933d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
19343397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
19353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
19363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1937dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// Declaration of a friend template.  For example:
1938dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///
1939dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// template <typename T> class A {
1940dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   friend class MyVector<T>; // not a friend template
1941c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein///   template <typename U> friend class B; // not a friend template
1942dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   template <typename U> friend class Foo<T>::Nested; // friend template
1943c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// };
1944c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// NOTE: This class is not currently in use.  All of the above
1945c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// will yield a FriendDecl, not a FriendTemplateDecl.
1946dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallclass FriendTemplateDecl : public Decl {
1947dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
194832f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
1949dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1950dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallprivate:
1951dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The number of template parameters;  always non-zero.
1952dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned NumParams;
1953dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1954dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The parameter list.
1955dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList **Params;
1956dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1957dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The declaration that's a friend of this class.
1958dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendUnion Friend;
1959dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1960dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Location of the 'friend' specifier.
1961dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation FriendLoc;
1962dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1963dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1964dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
1965dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     unsigned NParams,
1966dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     TemplateParameterList **Params,
1967dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     FriendUnion Friend,
1968dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     SourceLocation FriendLoc)
1969dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    : Decl(Decl::FriendTemplate, DC, Loc),
1970dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      NumParams(NParams),
1971dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Params(Params),
1972dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Friend(Friend),
1973dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      FriendLoc(FriendLoc)
1974dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  {}
1975dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1976554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  FriendTemplateDecl(EmptyShell Empty)
1977554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis    : Decl(Decl::FriendTemplate, Empty),
1978554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis      NumParams(0),
1979554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis      Params(0)
1980554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  {}
1981554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
1982dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
1983dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static FriendTemplateDecl *Create(ASTContext &Context,
1984dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    DeclContext *DC, SourceLocation Loc,
1985dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    unsigned NParams,
1986dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    TemplateParameterList **Params,
1987dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    FriendUnion Friend,
1988dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    SourceLocation FriendLoc);
1989dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1990554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  static FriendTemplateDecl *Create(ASTContext &Context, EmptyShell Empty);
1991554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
1992dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated type (or
1993dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a dependent member type of a templated type), return that
1994dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// type;  otherwise return null.
199532f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  TypeSourceInfo *getFriendType() const {
199632f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return Friend.dyn_cast<TypeSourceInfo*>();
1997dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1998dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1999dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated function (or
2000dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a member function of a templated type), return that type;
2001dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// otherwise return null.
2002dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  NamedDecl *getFriendDecl() const {
2003dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Friend.dyn_cast<NamedDecl*>();
2004dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2005dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2006dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// Retrieves the location of the 'friend' keyword.
2007dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation getFriendLoc() const {
2008dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return FriendLoc;
2009dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2010dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2011dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList *getTemplateParameterList(unsigned i) const {
2012dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    assert(i <= NumParams);
2013dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Params[i];
2014dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2015dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2016dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned getNumTemplateParameters() const {
2017dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return NumParams;
2018dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2019dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2020dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Implement isa/cast/dyncast/etc.
202180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
202280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2023dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static bool classof(const FriendTemplateDecl *D) { return true; }
2024554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2025d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
2026dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall};
2027dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
20283e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith/// Declaration of an alias template.  For example:
20293e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith///
20303e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
20313e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithclass TypeAliasTemplateDecl : public RedeclarableTemplateDecl,
20323e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                            public RedeclarableTemplate<TypeAliasTemplateDecl> {
20333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static void DeallocateCommon(void *Ptr);
20343e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20353e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithprotected:
20363e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  typedef RedeclarableTemplate<TypeAliasTemplateDecl> redeclarable_base;
20373e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20383e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  typedef CommonBase Common;
20393e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20403e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
20413e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                        TemplateParameterList *Params, NamedDecl *Decl)
20423e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
20433e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20443e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  CommonBase *newCommon(ASTContext &C);
20453e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20463e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  Common *getCommonPtr() {
20473e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
20483e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
20493e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20503e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithpublic:
20513e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// Get the underlying function declaration of the template.
20523e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasDecl *getTemplatedDecl() const {
20533e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return static_cast<TypeAliasDecl*>(TemplatedDecl);
20543e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
20553e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20563e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20573e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl *getCanonicalDecl() {
20583e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return redeclarable_base::getCanonicalDecl();
20593e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
20603e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  const TypeAliasTemplateDecl *getCanonicalDecl() const {
20613e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return redeclarable_base::getCanonicalDecl();
20623e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
20633e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20643e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Retrieve the previous declaration of this function template, or
20653e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// NULL if no such declaration exists.
20663e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl *getPreviousDeclaration() {
20673e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return redeclarable_base::getPreviousDeclaration();
20683e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
20693e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20703e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Retrieve the previous declaration of this function template, or
20713e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// NULL if no such declaration exists.
20723e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  const TypeAliasTemplateDecl *getPreviousDeclaration() const {
20733e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return redeclarable_base::getPreviousDeclaration();
20743e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
20753e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20763e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
20773e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return redeclarable_base::getInstantiatedFromMemberTemplate();
20783e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
20793e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20803e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20813e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Create a function template node.
20823e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
20833e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       SourceLocation L,
20843e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       DeclarationName Name,
20853e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       TemplateParameterList *Params,
20863e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       NamedDecl *Decl);
20873e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20883e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Create an empty alias template node.
20893e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static TypeAliasTemplateDecl *Create(ASTContext &C, EmptyShell);
20903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20913e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  // Implement isa/cast/dyncast support
20923e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
20933e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classof(const TypeAliasTemplateDecl *D) { return true; }
20943e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
20953e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20963e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  friend class ASTDeclReader;
20973e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  friend class ASTDeclWriter;
20983e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith};
20993e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2100e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
21011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
2102e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
2103e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
2104aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
2105aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
2106aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
2107