DeclTemplate.h revision 2dc57f42574c8b2cda72cae06c0220fd7fab8c0e
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//===----------------------------------------------------------------------===//
9d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
10d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \file
11d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Defines the C++ template declaration subclasses.
12d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
13aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
14aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
15aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
16aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#define LLVM_CLANG_AST_DECLTEMPLATE_H
17aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor#include "clang/AST/DeclCXX.h"
197c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor#include "clang/AST/Redeclarable.h"
20275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall#include "clang/AST/TemplateBase.h"
21f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor#include "llvm/ADT/PointerUnion.h"
22aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar#include "llvm/Support/Compiler.h"
233f3ce82674b44a58a2af7d90feb55acd906dd762Anders Carlsson#include <limits>
2455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
25aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregornamespace clang {
26aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
27aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList;
28aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateDecl;
299eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass RedeclarableTemplateDecl;
30aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl;
31aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass ClassTemplateDecl;
32c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorclass ClassTemplatePartialSpecializationDecl;
33aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTypeParmDecl;
34aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl;
35aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl;
363e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithclass TypeAliasTemplateDecl;
37ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplateDecl;
38ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplatePartialSpecializationDecl;
39aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
40f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor/// \brief Stores a template parameter of any kind.
41f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregortypedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
42f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor                            TemplateTemplateParmDecl*> TemplateParameter;
43f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
44d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Stores a list of template parameters for a TemplateDecl and its
45d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// derived classes.
46aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList {
47ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The location of the 'template' keyword.
48ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation TemplateLoc;
49ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
50ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The locations of the '<' and '>' angle brackets.
51ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation LAngleLoc, RAngleLoc;
52ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
53ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The number of template parameters in this template
54aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// parameter list.
556964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned NumParams : 31;
566964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
576964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// Whether this template parameter list contains an unexpanded parameter
586964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack.
596964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned ContainsUnexpandedParameterPack : 1;
60aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
61483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithprotected:
62ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
63bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                        NamedDecl **Params, unsigned NumParams,
64ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
66aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
674ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateParameterList *Create(const ASTContext &C,
68ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
69ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
70bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                                       NamedDecl **Params,
71ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
72ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
73aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
74d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Iterates through the template parameters in this list.
75bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl** iterator;
76aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
77d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Iterates through the template parameters in this list.
78bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl* const* const_iterator;
79aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
80bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
81aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
82bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor    return reinterpret_cast<NamedDecl * const *>(this + 1);
83aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
84aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator end() { return begin() + NumParams; }
85aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator end() const { return begin() + NumParams; }
86aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
87aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned size() const { return NumParams; }
88ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
895a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  llvm::ArrayRef<NamedDecl*> asArray() {
905a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    return llvm::ArrayRef<NamedDecl*>(begin(), size());
915a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
925a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  llvm::ArrayRef<const NamedDecl*> asArray() const {
935a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    return llvm::ArrayRef<const NamedDecl*>(begin(), size());
945a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
955a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
96bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  NamedDecl* getParam(unsigned Idx) {
97f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
98f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    return begin()[Idx];
99f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  }
100f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
101bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  const NamedDecl* getParam(unsigned Idx) const {
10240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
10340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return begin()[Idx];
10440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
10540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
106910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Returns the minimum number of arguments needed to form a
107d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// template specialization.
108d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  ///
109d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// This may be fewer than the number of template parameters, if some of
110d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// the parameters have default arguments or if there is a parameter pack.
11162cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  unsigned getMinRequiredArguments() const;
11262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
113ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Get the depth of this template parameter list in the set of
114ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template parameter lists.
115ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
116ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The first template parameter list in a declaration will have depth 0,
117ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// the second template parameter list will have depth 1, etc.
118ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
119ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1206964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Determine whether this template parameter list contains an
1216964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// unexpanded parameter pack.
1226964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool containsUnexpandedParameterPack() const {
1236964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return ContainsUnexpandedParameterPack;
1246964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
1256964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
126ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getTemplateLoc() const { return TemplateLoc; }
127ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getLAngleLoc() const { return LAngleLoc; }
128ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getRAngleLoc() const { return RAngleLoc; }
12962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
130aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY {
13162cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor    return SourceRange(TemplateLoc, RAngleLoc);
13262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  }
133aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
134aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
135d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Stores a list of template parameters for a TemplateDecl and its
136d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// derived classes. Suitable for creating on the stack.
137483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithtemplate<size_t N>
138483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithclass FixedSizeTemplateParameterList : public TemplateParameterList {
139483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  NamedDecl *Params[N];
140483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
141483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithpublic:
142ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  FixedSizeTemplateParameterList(SourceLocation TemplateLoc,
143ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                                 SourceLocation LAngleLoc,
144483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith                                 NamedDecl **Params, SourceLocation RAngleLoc) :
145483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith    TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) {
146483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  }
147483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith};
148483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
149127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A template argument list.
150127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentList {
151127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template argument list.
152127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
153127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// The integer value will be non-zero to indicate that this
15456ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// template argument list does own the pointer.
155910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> Arguments;
1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
157127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in this template
158127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument list.
159910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  unsigned NumArguments;
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
161be2fa7ebf01259b63dc52fe46c8d101c18e72269Craig Topper  TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
162be2fa7ebf01259b63dc52fe46c8d101c18e72269Craig Topper  void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
163910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
164910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs,
165910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                       bool Owned)
166910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    : Arguments(Args, Owned), NumArguments(NumArgs) { }
167910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
168aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
169ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Type used to indicate that the template argument list itself is a
170910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// stack object. It does not own its template arguments.
171910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  enum OnStackType { OnStack };
172910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
173910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Create a new template argument list that copies the given set of
174910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// template arguments.
175910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  static TemplateArgumentList *CreateCopy(ASTContext &Context,
176910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                          const TemplateArgument *Args,
177910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                          unsigned NumArgs);
178910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
179910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Construct a new, temporary template argument list on the stack.
180910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  ///
181910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// The template argument list does not own the template arguments
182910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// provided.
183ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  explicit TemplateArgumentList(OnStackType,
184910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                const TemplateArgument *Args, unsigned NumArgs)
185910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    : Arguments(Args, false), NumArguments(NumArgs) { }
186ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
187ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Produces a shallow copy of the given template argument list.
188ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ///
189910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// This operation assumes that the input argument list outlives it.
190910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// This takes the list as a pointer to avoid looking like a copy
191910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// constructor, since this really really isn't safe to use that
192910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// way.
193910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  explicit TemplateArgumentList(const TemplateArgumentList *Other)
194910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    : Arguments(Other->data(), false), NumArguments(Other->size()) { }
1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
196127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument &get(unsigned Idx) const {
198910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    assert(Idx < NumArguments && "Invalid template argument index");
199910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return data()[Idx];
200127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2055a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// \brief Produce this as an array ref.
2065a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  llvm::ArrayRef<TemplateArgument> asArray() const {
2075a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    return llvm::ArrayRef<TemplateArgument>(data(), size());
2085a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
2095a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
210127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in this
211127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list.
212910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  unsigned size() const { return NumArguments; }
2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
214910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Retrieve a pointer to the template argument list.
215910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  const TemplateArgument *data() const {
216910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return Arguments.getPointer();
217127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
218127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
220127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
221127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Templates
222127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
223aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
224d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief The base class of all kinds of template declarations (e.g.,
225d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// class, function, etc.).
226d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
227d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// The TemplateDecl class stores the list of template parameters and a
228d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// reference to the templated scoped declaration: the underlying AST node.
229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateDecl : public NamedDecl {
23099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
231127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // This is probably never used.
233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
234127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name)
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
236d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
237127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with the given name and parameters.
238127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
239127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
240127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
242d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
243127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
244127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
245127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
246127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               NamedDecl *Decl)
247127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
248127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParams(Params) { }
249127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
250127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the list of template parameters
251127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
252127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
253d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
254d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
255127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
256127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
257127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
258aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
25980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
26080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
2619a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstTemplate && K <= lastTemplate;
26280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  }
263aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
264aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY {
26580484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor    return SourceRange(TemplateParams->getTemplateLoc(),
26680484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor                       TemplatedDecl->getSourceRange().getEnd());
26780484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor  }
26880484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor
269127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
270127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
271127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
272ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2738731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidispublic:
2748731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Initialize the underlying templated declaration and
2758731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// template parameters.
2768731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
2778731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
2788731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplateParams == 0 && "TemplateParams already set!");
2798731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplatedDecl = templatedDecl;
2808731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplateParams = templateParams;
2818731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  }
282127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Provides information about a function template specialization,
285127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
286127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
287127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
288a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  FunctionTemplateSpecializationInfo(FunctionDecl *FD,
289a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     FunctionTemplateDecl *Template,
290a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     TemplateSpecializationKind TSK,
291a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     const TemplateArgumentList *TemplateArgs,
29271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis                       const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
293a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     SourceLocation POI)
294a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  : Function(FD),
295a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    Template(Template, TSK - 1),
296a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArguments(TemplateArgs),
297a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArgumentsAsWritten(TemplateArgsAsWritten),
298a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    PointOfInstantiation(POI) { }
299a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
300127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
301a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  static FunctionTemplateSpecializationInfo *
302a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
303a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         TemplateSpecializationKind TSK,
304a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentList *TemplateArgs,
305a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentListInfo *TemplateArgsAsWritten,
30671a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis         SourceLocation POI);
307a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
3081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template specialization that this structure
309127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
310127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template from which this function template
313127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
3141fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
315d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
316d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
318127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
319127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
320127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
3211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
322e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara  /// \brief The template arguments as written in the sources, if provided.
32371a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
324e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara
325b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief The point at which this function template specialization was
326ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// first instantiated.
327b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
328ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3291fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
3301fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
331d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
332d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Determine what kind of template specialization this is.
333d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
334d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    return (TemplateSpecializationKind)(Template.getInt() + 1);
335d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  }
336d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
3376ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  bool isExplicitSpecialization() const {
3386ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
3396ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  }
3406ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall
3415a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// \brief True if this declaration is an explicit specialization,
3425a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// explicit instantiation declaration, or explicit instantiation
3435a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// definition.
3445a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  bool isExplicitInstantiationOrSpecialization() const {
3455a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    switch (getTemplateSpecializationKind()) {
3465a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitSpecialization:
3475a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDeclaration:
3485a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDefinition:
3495a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return true;
3505a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
3515a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_Undeclared:
3525a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ImplicitInstantiation:
3535a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return false;
3545a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    }
3555a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    llvm_unreachable("bad template specialization kind");
3565a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
3575a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
358d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Set the template specialization kind.
359d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(TSK != TSK_Undeclared &&
361d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor         "Cannot encode TSK_Undeclared for a function template specialization");
362d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    Template.setInt(TSK - 1);
3631fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
365b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this function
366b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// template specialization.
367b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  ///
368b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// The point of instantiation may be an invalid source location if this
369b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// function has yet to be instantiated.
370ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getPointOfInstantiation() const {
371ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    return PointOfInstantiation;
372b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
373ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
374b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the (first) point of instantiation of this function template
375b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// specialization.
376b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
377b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
378b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
379ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
380127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
381910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    Profile(ID, TemplateArguments->data(),
382910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor            TemplateArguments->size(),
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Function->getASTContext());
384127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
388828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
389127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
390127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
391828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
3921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
393127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
395ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// \brief Provides information a specialization of a member of a class
396f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith/// template, which may be a member function, static data member,
397f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith/// member class or member enumeration.
3982db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorclass MemberSpecializationInfo {
39944e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // The member declaration from which this member was instantiated, and the
40044e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // manner in which the instantiation occurred (in the lower two bits).
40144e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
402ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
403b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  // The point at which this member was first instantiated.
404b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
405ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4062db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorpublic:
407ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  explicit
4089421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
4099421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis                           SourceLocation POI = SourceLocation())
4109421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
411ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    assert(TSK != TSK_Undeclared &&
41244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
41344e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  }
414ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4152db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Retrieve the member declaration from which this member was
4162db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// instantiated.
41744e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
418ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4192db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Determine what kind of template specialization this is.
4202db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
42144e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
4222db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
423ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4243892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall  bool isExplicitSpecialization() const {
4253892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
4263892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall  }
4273892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall
4282db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Set the template specialization kind.
4292db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
430ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    assert(TSK != TSK_Undeclared &&
43144e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
43244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    MemberAndTSK.setInt(TSK - 1);
4332db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
434ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
435ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieve the first point of instantiation of this member.
436b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// If the point of instantiation is an invalid location, then this member
437b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// has not yet been instantiated.
438ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getPointOfInstantiation() const {
439ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    return PointOfInstantiation;
440b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
441ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
442b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the first point of instantiation.
443b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
444b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
445b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
4462db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor};
447af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
448af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// \brief Provides information about a dependent function-template
449d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// specialization declaration.
450d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
451d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// Since explicit function template specialization and instantiation
452d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// declarations can only appear in namespace scope, and you can only
453d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// specialize a member of a fully-specialized class, the only way to
454d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// get one of these is in a friend declaration like the following:
455af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///
456d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
457d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<class T> void foo(T);
458d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<class T> class A {
459af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///     friend void foo<>(T);
460af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   };
461d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
462af2094e7cecadf36667deb61a83587ffdd979bd3John McCallclass DependentFunctionTemplateSpecializationInfo {
463e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct CA {
464e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    /// The number of potential template candidates.
465e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned NumTemplates;
466e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
467e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    /// The number of template arguments.
468e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned NumArgs;
469e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
470e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
471af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  union {
472af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // Force sizeof to be a multiple of sizeof(void*) so that the
473af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // trailing data is aligned.
474ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    void *Aligner;
475e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct CA d;
476af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  };
477af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
478af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// The locations of the left and right angle brackets.
479af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceRange AngleLocs;
480af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
481af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl * const *getTemplates() const {
482af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
483af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
484af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
485af2094e7cecadf36667deb61a83587ffdd979bd3John McCallpublic:
486af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  DependentFunctionTemplateSpecializationInfo(
487af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const UnresolvedSetImpl &Templates,
488af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const TemplateArgumentListInfo &TemplateArgs);
489af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
490af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of function templates that this might
491af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// be a specialization of.
492af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplates() const {
493af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumTemplates;
494af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
495af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
496af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the i'th template candidate.
497af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl *getTemplate(unsigned I) const {
498af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplates() && "template index out of range");
499af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplates()[I];
500af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
501af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
502e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  /// \brief Returns the explicit template arguments that were given.
503e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  const TemplateArgumentLoc *getTemplateArgs() const {
504e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor    return reinterpret_cast<const TemplateArgumentLoc*>(
505ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                                            &getTemplates()[getNumTemplates()]);
506e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  }
507e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor
508af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of explicit template arguments that were given.
509af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplateArgs() const {
510af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumArgs;
511af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
512af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
513af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the nth template argument.
514af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
515af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplateArgs() && "template arg index out of range");
516af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplateArgs()[I];
517af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
518af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
519af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getLAngleLoc() const {
520af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getBegin();
521af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
522af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
523af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getRAngleLoc() const {
524af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getEnd();
525af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
526af2094e7cecadf36667deb61a83587ffdd979bd3John McCall};
527ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
5289eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a redeclarable template.
5297c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass RedeclarableTemplateDecl : public TemplateDecl,
5307c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor                                 public Redeclarable<RedeclarableTemplateDecl>
5317c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor{
5327c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
5337c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  virtual RedeclarableTemplateDecl *getNextRedeclaration() {
5347c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return RedeclLink.getNext();
5359eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
536ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  virtual RedeclarableTemplateDecl *getPreviousDeclImpl() {
537ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getPreviousDecl();
538ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
539ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  virtual RedeclarableTemplateDecl *getMostRecentDeclImpl() {
540ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getMostRecentDecl();
541ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
5421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
54444dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  template <typename EntryType> struct SpecEntryTraits {
54544dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    typedef EntryType DeclType;
54644dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
547ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    static DeclType *getMostRecentDecl(EntryType *D) {
548ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      return D->getMostRecentDecl();
54944dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    }
55044dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  };
55144dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
5529f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType,
5539f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _SETraits = SpecEntryTraits<EntryType>,
5549f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _DeclType = typename _SETraits::DeclType>
5559f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  class SpecIterator : public std::iterator<std::forward_iterator_tag,
5569f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, ptrdiff_t,
5579f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, _DeclType*> {
5589f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _SETraits SETraits;
5599f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _DeclType DeclType;
5609f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
561d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    typedef typename llvm::FoldingSetVector<EntryType>::iterator
562d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth      SetIteratorType;
5639f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5649f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SetIteratorType SetIter;
5659f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5669f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  public:
5679f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator() : SetIter() {}
5689f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
5699f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5709f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator*() const {
571ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      return SETraits::getMostRecentDecl(&*SetIter);
5729f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5739f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator->() const { return **this; }
5749f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5759f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator &operator++() { ++SetIter; return *this; }
5769f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator operator++(int) {
5779f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      SpecIterator tmp(*this);
5789f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      ++(*this);
5799f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return tmp;
5809f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5819f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5829f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator==(SpecIterator Other) const {
5839f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter == Other.SetIter;
5849f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5859f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator!=(SpecIterator Other) const {
5869f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter != Other.SetIter;
5879f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5889f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  };
5899f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5909f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType>
591e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  static SpecIterator<EntryType>
592d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
5939f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
5949f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
5959f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5964048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne  template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
597d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
5984048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne                         const TemplateArgument *Args, unsigned NumArgs,
5994048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne                         void *&InsertPos);
6004048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne
6019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct CommonBase {
6029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    CommonBase() : InstantiatedFromMember(0, false) { }
6039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
6049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// \brief The template from which this was most
605d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// directly instantiated (or null).
606fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    ///
6079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// The boolean value indicates whether this template
608fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// was explicitly specialized.
6099eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
6109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne      InstantiatedFromMember;
6113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
6121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6137c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  /// \brief Pointer to the common data shared by all declarations of this
6147c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  /// template.
615b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  mutable CommonBase *Common;
6167c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor
6179eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
6189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// the same template. Calling this routine may implicitly allocate memory
6199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// for the common pointer.
620b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  CommonBase *getCommonPtr() const;
6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
622b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  virtual CommonBase *newCommon(ASTContext &C) const = 0;
6232c853e401ca406d417eb916e867226050e7be06bArgyrios Kyrtzidis
6249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  // Construct a template decl with name, parameters, and templated element.
6259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
6269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                           DeclarationName Name, TemplateParameterList *Params,
6279eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                           NamedDecl *Decl)
6287c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { }
6291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
6319eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  template <class decl_type> friend class RedeclarableTemplate;
6329eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
633d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Retrieves the canonical declaration of this template.
634bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola  RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDecl(); }
635bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola  const RedeclarableTemplateDecl *getCanonicalDecl() const {
636bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    return getFirstDecl();
637ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
638ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
639ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \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
657b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  bool isMemberSpecialization() const {
6589eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCommonPtr()->InstantiatedFromMember.getInt();
6599eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
660ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
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  }
667ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
6680f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \brief Retrieve the member template from which this template was
6690f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// instantiated, or NULL if this template was not instantiated from a
6700f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// member template.
6710f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6720f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// A template is instantiated from a member template when the member
6730f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template itself is part of a class template (or member thereof). For
6740f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// example, given
6750f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6760f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \code
6770f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename T>
6780f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// struct X {
6790f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///   template<typename U> void f(T, U);
6800f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// };
6810f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6820f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// void test(X<int> x) {
6830f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///   x.f(1, 'a');
6840f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// };
6850f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \endcode
6860f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6870f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \c X<int>::f is a FunctionTemplateDecl that describes the function
6880f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template
6890f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6900f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \code
6910f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename U> void X<int>::f(int, U);
6920f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \endcode
6930f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6940f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// which was itself created during the instantiation of \c X<int>. Calling
6950f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
696d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// retrieve the FunctionTemplateDecl for the original template \c f within
6970f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// the class template \c X<T>, i.e.,
6980f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6990f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \code
7000f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename T>
7010f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename U>
7020f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// void X<T>::f(T, U);
7030f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \endcode
704b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
7057c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return getCommonPtr()->InstantiatedFromMember.getPointer();
7067c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  }
7077c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor
7087c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
7097c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
7107c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    getCommonPtr()->InstantiatedFromMember.setPointer(TD);
7119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7129eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
713a54fbf2499c7cc999e22abb9be484ce976ed9689Douglas Gregor  typedef redeclarable_base::redecl_iterator redecl_iterator;
714ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_begin;
715ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_end;
716ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getPreviousDecl;
717ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getMostRecentDecl;
7187693b32af6863c63fcaf4de087760740ee675f71Rafael Espindola  using redeclarable_base::isFirstDecl;
719f785a7d611404cf4747287a2bbc59b4d0e6a5a8cDouglas Gregor
7209eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  // Implement isa/cast/dyncast/etc.
7219eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
7229eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classofKind(Kind K) {
7239eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
7249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7267c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  friend class ASTReader;
727d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
7283397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
7299eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne};
7309eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
73144dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbournetemplate <> struct RedeclarableTemplateDecl::
73244dd0b440efdb37ff4c6e49f243faa3b0580b120Peter CollingbourneSpecEntryTraits<FunctionTemplateSpecializationInfo> {
73344dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  typedef FunctionDecl DeclType;
73444dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
73544dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  static DeclType *
736ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  getMostRecentDecl(FunctionTemplateSpecializationInfo *I) {
737ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return I->Function->getMostRecentDecl();
73844dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  }
73944dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne};
74044dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
7419eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a template function.
7427c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass FunctionTemplateDecl : public RedeclarableTemplateDecl {
7439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static void DeallocateCommon(void *Ptr);
7449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
7469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Data that is common to all of the declarations of a given
7479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
7489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
7496982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    Common() : InjectedArgs(), LazySpecializations() { }
750ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
7519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// \brief The function template specializations for this function
7529eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// template, including explicit specializations and instantiations.
753d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
754ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
755c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// \brief The set of "injected" template arguments used within this
756c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// function template.
757c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    ///
758c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// This pointer refers to the template arguments (there are as
759c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// many template arguments as template parameaters) for the function
760c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// template, and is allocated lazily, since most function templates do not
761c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// require the use of this information.
762c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    TemplateArgument *InjectedArgs;
7636982bf4d77bc57a85ee173b631729fce673f16efRichard Smith
7646982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// \brief If non-null, points to an array of specializations known only
7656982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// by their external declaration IDs.
7666982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    ///
7676982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// The first value in the array is the number of of specializations
7686982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// that follow.
7696982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    uint32_t *LazySpecializations;
7709eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  };
7719eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7729eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
7739eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                       TemplateParameterList *Params, NamedDecl *Decl)
7749eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
7759eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
776b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  CommonBase *newCommon(ASTContext &C) const;
7779eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
778e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  Common *getCommonPtr() const {
7799eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
780fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
7819eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7826b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  friend class FunctionDecl;
783da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor
7846982bf4d77bc57a85ee173b631729fce673f16efRichard Smith  /// \brief Load any lazily-loaded specializations from the external source.
7856982bf4d77bc57a85ee173b631729fce673f16efRichard Smith  void LoadLazySpecializations() const;
7866982bf4d77bc57a85ee173b631729fce673f16efRichard Smith
7879eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the set of function template specializations of this
7889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
789d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
7906982bf4d77bc57a85ee173b631729fce673f16efRichard Smith  getSpecializations() const;
7915bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl
7925bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  /// \brief Add a specialization of this function template.
7935bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  ///
794d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  /// \param InsertPos Insert position in the FoldingSetVector, must have been
7955bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  ///        retrieved by an earlier call to findSpecialization().
7965bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  void addSpecialization(FunctionTemplateSpecializationInfo* Info,
7975bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl                         void *InsertPos);
798ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
7999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbournepublic:
8009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// Get the underlying function declaration of the template.
8019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionDecl *getTemplatedDecl() const {
8029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<FunctionDecl*>(TemplatedDecl);
8039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
80513fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// Returns whether this template declaration defines the primary
80613fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// pattern.
80713fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
80813fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
80913fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
81013fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
8119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Return the specialization with the provided arguments if it exists,
8129eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// otherwise return the insertion point.
8139eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionDecl *findSpecialization(const TemplateArgument *Args,
8149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                                   unsigned NumArgs, void *&InsertPos);
8159eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8169eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getCanonicalDecl() {
8177c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<FunctionTemplateDecl>(
8187c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
8199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8209eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const FunctionTemplateDecl *getCanonicalDecl() const {
8217c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<FunctionTemplateDecl>(
8227c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
8239eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this function template, or
8269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
827ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  FunctionTemplateDecl *getPreviousDecl() {
8287c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<FunctionTemplateDecl>(
8292dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
8309eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8319eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8329eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this function template, or
8339eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
834ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  const FunctionTemplateDecl *getPreviousDecl() const {
8357c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<FunctionTemplateDecl>(
8362dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman       static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
8379eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8389eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8399eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
8407c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<FunctionTemplateDecl>(
8417c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
8429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8449f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
8459f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
846e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_begin() const {
8479f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
8489f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8499f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
850e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_end() const {
8519f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
8529f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8539f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
854c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// \brief Retrieve the "injected" template arguments that correspond to the
855c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// template parameters of this function template.
856ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ///
857c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// Although the C++ standard has no notion of the "injected" template
858c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// arguments for a function template, the notion is convenient when
859c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// we need to perform substitutions inside the definition of a function
860ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// template.
8617a9f7c7c68673c46d6e2b83fec6f4cbfbd25f475Richard Smith  ArrayRef<TemplateArgument> getInjectedTemplateArgs();
862ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
8639a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  /// \brief Create a function template node.
864127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
865127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
866127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
867127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
868127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
8693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
8709a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  /// \brief Create an empty function template node.
8711e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
8729a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
873127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
87480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
87580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == FunctionTemplate; }
876c8f9af2943699ff623ca08f2e5ed4d72e0351189Argyrios Kyrtzidis
877d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
8783397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
879127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
880d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
881127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
882127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
883127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
88440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
885d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Defines the position of a template parameter within a template
886d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// parameter list.
887d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
888d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// Because template parameter can be listed
889127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
890127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
891127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
892127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
893127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
8941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass TemplateParmPosition {
895127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
896127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
897127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
898127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
899b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie  { /* llvm_unreachable("Cannot create positionless template parameter"); */ }
9003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
901127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
902127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
903127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
9043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
905127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
906127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
907127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
908127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
9093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
910127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
911127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
912127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
913b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setDepth(unsigned D) { Depth = D; }
9143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
915127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
916127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
917b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setPosition(unsigned P) { Position = P; }
9181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
919127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
920127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
921127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
9223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
923d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of a template type parameter.
924d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
925d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// For example, "T" in
926d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
927127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
928d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
929127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
930127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
931d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// the 'typename' keyword.
932d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  ///
933d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// If false, it was declared with the 'class' keyword.
934127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
9353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
936127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
937127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
938127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
9393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
940127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
941a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *DefaultArgument;
942127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
943344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara  TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
944344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                       SourceLocation IdLoc, IdentifierInfo *Id,
9454fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth                       bool Typename)
946344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara    : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
9474fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth      InheritedDefault(false), DefaultArgument() { }
9483e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
949483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  /// Sema creates these on the stack during auto type deduction.
950483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  friend class Sema;
951483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
952127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
9534ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
954344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      SourceLocation KeyLoc,
955344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      SourceLocation NameLoc,
956344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      unsigned D, unsigned P,
957127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
958127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
9591e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
9601e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                  unsigned ID);
961c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
962127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
963d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// the 'typename' keyword.
964d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  ///
965d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// If not, it was declared with the 'class' keyword.
966127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
967c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
968127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
969127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
970833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  bool hasDefaultArgument() const { return DefaultArgument != 0; }
971199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
972127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
973833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
97440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
975833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the default argument's source information, if any.
976a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
977833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
978833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the location of the default argument declaration.
979833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  SourceLocation getDefaultArgumentLoc() const;
98040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
981127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
982127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
983127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
984f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
985127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
986127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
987127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
988a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
989127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
990127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
991f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
99240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
993833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Removes the default argument of this template parameter.
994833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  void removeDefaultArgument() {
995833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    DefaultArgument = 0;
996833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    InheritedDefault = false;
997833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
998ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
9998731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Set whether this template type parameter was declared with
10008731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// the 'typename' or 'class' keyword.
10018731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
10028731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
1003ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the depth of the template parameter.
1004ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
1005ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1006ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the index of the template parameter.
1007ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getIndex() const;
1008ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1009127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
10104fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth  bool isParameterPack() const;
1011fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
1012aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
101377d4ee2bfc90b77ec8b818de985cd4aceeef757bAbramo Bagnara
1014127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
101580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
101680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
10173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
10183e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1019127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1020127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
1021127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1022127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
1023127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1024127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
102576a40219ee5624d78aba167dce02bdbaa930955fJohn McCall  : public DeclaratorDecl, protected TemplateParmPosition {
1026d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief The default template argument, if any, and whether or not
1027d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// it was inherited.
1028d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
1029127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
103010738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
103110738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  // down here to save memory.
1032ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
103310738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \brief Whether this non-type template parameter is a parameter pack.
103410738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  bool ParameterPack;
1035ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1036ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Whether this non-type template parameter is an "expanded"
10376952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// parameter pack, meaning that its type is a pack expansion and we
10386952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// already know the set of types that expansion expands to.
10396952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  bool ExpandedParameterPack;
1040ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
10416952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief The number of types in an expanded parameter pack.
10426952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  unsigned NumExpandedTypes;
1043ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1044ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1045ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          SourceLocation IdLoc, unsigned D, unsigned P,
1046ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          IdentifierInfo *Id, QualType T,
104710738d36b150aa65206890c1c845cdba076e4200Douglas Gregor                          bool ParameterPack, TypeSourceInfo *TInfo)
1048ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
104910738d36b150aa65206890c1c845cdba076e4200Douglas Gregor      TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
10506952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      ParameterPack(ParameterPack), ExpandedParameterPack(false),
10516952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      NumExpandedTypes(0)
1052127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
1053127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1054ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1055ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          SourceLocation IdLoc, unsigned D, unsigned P,
1056ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          IdentifierInfo *Id, QualType T,
10576952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          TypeSourceInfo *TInfo,
10586952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          const QualType *ExpandedTypes,
10596952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          unsigned NumExpandedTypes,
10606952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          TypeSourceInfo **ExpandedTInfos);
10616952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
106210738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  friend class ASTDeclReader;
1063ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
10641c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
1065127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
1066ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1067ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1068ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
10699ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
10706952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  static NonTypeTemplateParmDecl *
1071ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1072ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1073ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         QualType T, TypeSourceInfo *TInfo,
10746952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor         const QualType *ExpandedTypes, unsigned NumExpandedTypes,
10756952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor         TypeSourceInfo **ExpandedTInfos);
10766952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
10771e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
10781e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned ID);
10791e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
10801e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned ID,
10811e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned NumExpandedTypes);
10821e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1083127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1084b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setDepth;
1085127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1086b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setPosition;
1087127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
10881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1089aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
109076a40219ee5624d78aba167dce02bdbaa930955fJohn McCall
1091127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1092127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1093d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
1094d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer() != 0;
1095d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1096fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
1097127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1098d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  Expr *getDefaultArgument() const {
1099d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer();
1100d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1101127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1102127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
1103127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
1104127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1105d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1106d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1107d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1108d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getInt();
1109d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1110d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1111d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1112d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1113d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1114d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(Expr *DefArg, bool Inherited) {
1115d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(DefArg);
1116d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(Inherited);
1117d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1118d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1119d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1120d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
1121d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(0);
1122d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(false);
11233b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
1124127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
112510738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \brief Whether this parameter is a non-type template parameter pack.
112610738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  ///
112710738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// If the parameter is a parameter pack, the type may be a
112810738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \c PackExpansionType. In the following example, the \c Dims parameter
112910738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// is a parameter pack (whose type is 'unsigned').
113010738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  ///
113110738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \code
113210738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// template<typename T, unsigned ...Dims> struct multi_array;
113310738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \endcode
113410738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  bool isParameterPack() const { return ParameterPack; }
1135ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
11366964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this parameter pack is a pack expansion.
11376964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
11386964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// A non-type template parameter pack is a pack expansion if its type
11396964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// contains an unexpanded parameter pack. In this case, we will have
11406964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// built a PackExpansionType wrapping the type.
11416964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool isPackExpansion() const {
11426964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return ParameterPack && getType()->getAs<PackExpansionType>();
11436964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
11446964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
11456952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief Whether this parameter is a non-type template parameter pack
11466964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// that has a known list of different types at different positions.
11476952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11486952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// A parameter pack is an expanded parameter pack when the original
11496952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// parameter pack's type was itself a pack expansion, and that expansion
11506952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// has already been expanded. For example, given:
11516952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11526952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \code
11536952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// template<typename ...Types>
11546952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// struct X {
11556952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///   template<Types ...Values>
11566952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///   struct Y { /* ... */ };
11576952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// };
11586952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \endcode
1159ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ///
11606952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// The parameter pack \c Values has a \c PackExpansionType as its type,
11616952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// which expands \c Types. When \c Types is supplied with template arguments
1162ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// by instantiating \c X, the instantiation of \c Values becomes an
1163ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// expanded parameter pack. For example, instantiating
11646952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \c X<int, unsigned int> results in \c Values being an expanded parameter
11656952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// pack with expansion types \c int and \c unsigned int.
11666952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
1167ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
11686952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// return the expansion types.
11696952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1170ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1171ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieves the number of expansion types in an expanded parameter
1172ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// pack.
11736952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  unsigned getNumExpansionTypes() const {
11746952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(ExpandedParameterPack && "Not an expansion parameter pack");
11756952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return NumExpandedTypes;
11766952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11776952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1178ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieve a particular expansion type within an expanded parameter
11796952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// pack.
11806952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  QualType getExpansionType(unsigned I) const {
11816952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
11826952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
11836952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return QualType::getFromOpaquePtr(TypesAndInfos[2*I]);
11846952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11856952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1186ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieve a particular expansion type source info within an
11876952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// expanded parameter pack.
11886952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
11896952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
11906952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
11916952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]);
11926952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11936952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1194127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
119580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
119680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
11971c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
11981c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
1199127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
1200127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
1201127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
1203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1204127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
1205127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
12061e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregorclass TemplateTemplateParmDecl : public TemplateDecl,
12071e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                 protected TemplateParmPosition
12081e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor{
120999ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
12107e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1211d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// DefaultArgument - The default template argument, if any.
1212788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  TemplateArgumentLoc DefaultArgument;
1213d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// Whether or not the default argument was inherited.
1214d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool DefaultArgumentWasInherited;
12157e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
121661c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  /// \brief Whether this parameter is a parameter pack.
121761c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  bool ParameterPack;
1218ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
12196964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this template template parameter is an "expanded"
12206964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// parameter pack, meaning that it is a pack expansion and we
12216964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// already know the set of template parameters that expansion expands to.
12226964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool ExpandedParameterPack;
12236964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
12246964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief The number of parameters in an expanded parameter pack.
12256964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned NumExpandedParams;
12266964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
1227127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
122861c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                           unsigned D, unsigned P, bool ParameterPack,
1229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
1230127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1231d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      TemplateParmPosition(D, P), DefaultArgument(),
12326964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith      DefaultArgumentWasInherited(false), ParameterPack(ParameterPack),
12336964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith      ExpandedParameterPack(false), NumExpandedParams(0)
1234127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
12357e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
12366964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
12376964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           unsigned D, unsigned P,
12386964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           IdentifierInfo *Id, TemplateParameterList *Params,
12396964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           unsigned NumExpansions,
12406964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           TemplateParameterList * const *Expansions);
12416964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
1242127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
12434ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
1244127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
124561c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                                          unsigned P, bool ParameterPack,
124661c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                                          IdentifierInfo *Id,
1247127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
12486964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
12496964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          SourceLocation L, unsigned D,
12506964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          unsigned P,
12516964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          IdentifierInfo *Id,
12526964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          TemplateParameterList *Params,
1253cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko                                 ArrayRef<TemplateParameterList *> Expansions);
12547e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
12556964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
12561e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                      unsigned ID);
12576964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
12586964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                                      unsigned ID,
12596964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                                      unsigned NumExpansions);
12601e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1261127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1262127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1263127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
12641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1265d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \brief Whether this template template parameter is a template
1266d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// parameter pack.
1267d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  ///
1268d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \code
1269d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// template<template <class T> ...MetaFunctions> struct Apply;
1270d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \endcode
127161c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  bool isParameterPack() const { return ParameterPack; }
1272d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
12736964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this parameter pack is a pack expansion.
12746964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12756964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// A template template parameter pack is a pack expansion if its template
12766964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// parameter list contains an unexpanded parameter pack.
12776964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool isPackExpansion() const {
12786964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return ParameterPack &&
12796964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith           getTemplateParameters()->containsUnexpandedParameterPack();
12806964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
12816964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
12826964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this parameter is a template template parameter pack that
12836964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// has a known list of different template parameter lists at different
12846964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// positions.
12856964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12866964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// A parameter pack is an expanded parameter pack when the original parameter
12876964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack's template parameter list was itself a pack expansion, and that
12886964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// expansion has already been expanded. For exampe, given:
12896964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12906964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \code
12916964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// template<typename...Types> struct Outer {
12926964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///   template<template<Types> class...Templates> struct Inner;
12936964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// };
12946964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \endcode
12956964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12966964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// The parameter pack \c Templates is a pack expansion, which expands the
12976964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack \c Types. When \c Types is supplied with template arguments by
12986964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// instantiating \c Outer, the instantiation of \c Templates is an expanded
12996964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// parameter pack.
13006964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
13016964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
13026964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Retrieves the number of expansion template parameters in
13036964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// an expanded parameter pack.
13046964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned getNumExpansionTemplateParameters() const {
13056964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    assert(ExpandedParameterPack && "Not an expansion parameter pack");
13066964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return NumExpandedParams;
13076964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
13086964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
13096964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Retrieve a particular expansion type within an expanded parameter
13106964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack.
13116964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
13126964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    assert(I < NumExpandedParams && "Out-of-range expansion type index");
13136964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I];
13146964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
13156964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
1316127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1317127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1318d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
1319d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return !DefaultArgument.getArgument().isNull();
1320788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
13217e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1322127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1323d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  const TemplateArgumentLoc &getDefaultArgument() const {
1324d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgument;
1325d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1326d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1327d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Retrieve the location of the default argument, if any.
1328d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  SourceLocation getDefaultArgumentLoc() const;
1329d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1330d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1331d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1332d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1333d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentWasInherited;
1334788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
13357e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1336d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1337d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1338d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1339d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
1340127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
1341d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = Inherited;
1342d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1343d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1344d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1345d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
1346d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgument = TemplateArgumentLoc();
1347d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = false;
1348127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
13497e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1350aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY {
1351fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    SourceLocation End = getLocation();
1352fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (hasDefaultArgument() && !defaultArgumentWasInherited())
1353fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      End = getDefaultArgument().getSourceRange().getEnd();
1354fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1355fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  }
1356fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1357127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
135880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
135980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1360bfcc92c3476ada55ceeea49e43e6d2e083252830Argyrios Kyrtzidis
1361d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
13623397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
13637e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
13647e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
13653e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
13663e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
13673e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
13683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
13693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
13703e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
13713e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
13723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
13733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
13741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
13751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// template<>
13763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
13773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
13781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplateSpecializationDecl
13793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
13801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Structure that stores information about a class template
138237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
138337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
138437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
138537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
138637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
138737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
13881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
138937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
139037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
1391d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    const TemplateArgumentList *TemplateArgs;
139237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
13931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
139537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
139637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
13973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1398c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
1399c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  struct ExplicitSpecializationInfo {
1400c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The type-as-written.
1401c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    TypeSourceInfo *TypeAsWritten;
1402c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the extern keyword.
1403c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation ExternLoc;
1404c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the template keyword.
1405c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation TemplateKeywordLoc;
1406c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1407c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitSpecializationInfo()
1408c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara      : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
1409c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  };
1410c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1411c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
14123cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// Does not apply to implicit specializations.
1413c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  ExplicitSpecializationInfo *ExplicitInfo;
14143cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
14157e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
1416d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  const TemplateArgumentList *TemplateArgs;
1417cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
14189cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief The point where this template was instantiated (if any)
14199cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation PointOfInstantiation;
14209cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
1421cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
1422cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
1423d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  unsigned SpecializationKind : 3;
1424cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1425c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
142613c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
1427ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                  DeclContext *DC, SourceLocation StartLoc,
1428ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                  SourceLocation IdLoc,
14293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
1430910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                  const TemplateArgument *Args,
1431910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                  unsigned NumArgs,
14328e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
14331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
143494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  explicit ClassTemplateSpecializationDecl(Kind DK);
143594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
14363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
14373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
1438ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1439ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara         SourceLocation StartLoc, SourceLocation IdLoc,
14403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
1441910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         const TemplateArgument *Args,
1442910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         unsigned NumArgs,
1443cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
1444b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  static ClassTemplateSpecializationDecl *
14451e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  CreateDeserialized(ASTContext &C, unsigned ID);
144694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
14475eada844fa70b6e2bc941dd7306f7a4fb1e8529dBenjamin Kramer  virtual void getNameForDiagnostic(raw_ostream &OS,
1448da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor                                    const PrintingPolicy &Policy,
1449da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor                                    bool Qualified) const;
1450da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor
1451ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  ClassTemplateSpecializationDecl *getMostRecentDecl() {
14522dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman    CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
14532dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman                              this)->getMostRecentDecl();
1454b60fae50d38a0291e1c5731b2fb22849d26ca342Richard Smith    while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
1455cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis      // FIXME: Does injected class name need to be in the redeclarations chain?
1456ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
1457ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      Recent = Recent->getPreviousDecl();
1458cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    }
1459cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplateSpecializationDecl>(Recent);
1460cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1461cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
14623e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
146337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
14643e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
14651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the template arguments of the class template
146637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
14671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgumentList &getTemplateArgs() const {
1468910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return *TemplateArgs;
14693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
14703e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1471cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
1472cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
1473cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
1474cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
1475cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1476cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
14776ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  bool isExplicitSpecialization() const {
14786ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall    return getSpecializationKind() == TSK_ExplicitSpecialization;
14796ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  }
14806ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall
14815a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// \brief True if this declaration is an explicit specialization,
14825a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// explicit instantiation declaration, or explicit instantiation
14835a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// definition.
14845a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  bool isExplicitInstantiationOrSpecialization() const {
14855a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    switch (getTemplateSpecializationKind()) {
14865a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitSpecialization:
14875a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDeclaration:
14885a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDefinition:
14895a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return true;
14905a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
14915a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_Undeclared:
14925a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ImplicitInstantiation:
14935a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return false;
14945a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    }
14955a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    llvm_unreachable("bad template specialization kind");
14965a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
14975a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
1498cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
1499cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
1500cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1501cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
15029cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief Get the point of instantiation (if any), or null if none.
15039cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation getPointOfInstantiation() const {
15049cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    return PointOfInstantiation;
15059cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
15069cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
15079cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  void setPointOfInstantiation(SourceLocation Loc) {
15089cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    assert(Loc.isValid() && "point of instantiation must be valid!");
15099cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    PointOfInstantiation = Loc;
15109cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
15119cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
151237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
151337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
151437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
151537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
15161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::PointerUnion<ClassTemplateDecl *,
151737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
151837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
151937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
1520d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
1521d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
1522e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor      return llvm::PointerUnion<ClassTemplateDecl *,
1523e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor                                ClassTemplatePartialSpecializationDecl *>();
15241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
152637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
152737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
15281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1529f8c12146fa2153a6d97b7c92d27d2ece0cd26e79Dmitri Gribenko    return SpecializedTemplate.get<ClassTemplateDecl*>();
153037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
15311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
153294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Retrieve the class template or class template partial
153394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// specialization which was specialized by this.
153494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  llvm::PointerUnion<ClassTemplateDecl *,
153594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis                     ClassTemplatePartialSpecializationDecl *>
153694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  getSpecializedTemplateOrPartial() const {
153794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    if (SpecializedPartialSpecialization *PartialSpec
153894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
153994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      return PartialSpec->PartialSpecialization;
154094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1541f8c12146fa2153a6d97b7c92d27d2ece0cd26e79Dmitri Gribenko    return SpecializedTemplate.get<ClassTemplateDecl*>();
154294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
154394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
154437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
154537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
154637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
154737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
154837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
154937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
155037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
155137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
155237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
155337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
155437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
155537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
15561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
155737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
155837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
15591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
156037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
156137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
15621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
156337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
156437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
156537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
156637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
1567d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith                          const TemplateArgumentList *TemplateArgs) {
156894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
156994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Already set to a class template partial specialization!");
15701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SpecializedPartialSpecialization *PS
157137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
157237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
157337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
157437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
157537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
15761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
157794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Note that this class template specialization is an instantiation
157894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// of the given class template.
157994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
158094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
158194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Previously set to a class template partial specialization!");
158294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    SpecializedTemplate = TemplDecl;
158394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
158494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1585fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
1586fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
15873cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  void setTypeAsWritten(TypeSourceInfo *T) {
1588db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1589db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1590c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TypeAsWritten = T;
15913cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  }
15923cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Gets the type of this specialization as it was written by
15933cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// the user, if it was so written.
15943cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  TypeSourceInfo *getTypeAsWritten() const {
1595c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
1596c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1597c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1598c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the extern keyword, if present.
1599c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getExternLoc() const {
1600c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
1601c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1602c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the extern keyword.
1603c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setExternLoc(SourceLocation Loc) {
1604db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1605db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1606c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->ExternLoc = Loc;
1607c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1608c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1609c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the template keyword.
1610c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setTemplateKeywordLoc(SourceLocation Loc) {
1611db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1612db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1613c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TemplateKeywordLoc = Loc;
1614c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1615c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the template keyword, if present.
1616c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getTemplateKeywordLoc() const {
1617c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
1618fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
1619fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
1620aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
16214a85a73466bfb541cd9c7b57a99292a0b6900b9bAbramo Bagnara
1622c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1623910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
1624c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1625c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
16261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
16271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
1628828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
16290ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
16303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
1631828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
16323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
16333e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
163480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
163580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
16369a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstClassTemplateSpecialization &&
16379a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt           K <= lastClassTemplateSpecialization;
16383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
16393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1640586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclReader;
1641586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclWriter;
1642c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1643c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
16441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplatePartialSpecializationDecl
16451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public ClassTemplateSpecializationDecl {
164699ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
164799ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
16481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The list of template parameters
1649c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1650c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1651833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief The source info for the template arguments as written.
16523cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// FIXME: redundant with TypeAsWritten?
1653c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *ArgsAsWritten;
1654833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1655ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The class template partial specialization from which this
1656ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// class template partial specialization was instantiated.
1657ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1658ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The boolean value will be true to indicate that this class template
1659ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// partial specialization was specialized at this level.
1660ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
1661ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      InstantiatedFromMember;
1662ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
166313c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1664ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         DeclContext *DC,
1665ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         SourceLocation StartLoc,
1666ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         SourceLocation IdLoc,
1667c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1668c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
1669910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                         const TemplateArgument *Args,
1670910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                         unsigned NumArgs,
1671c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella                               const ASTTemplateArgumentListInfo *ArgsAsWritten,
167237fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith                               ClassTemplatePartialSpecializationDecl *PrevDecl);
1673ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
167494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl()
167594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
167637fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith      TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { }
1677c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1678c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1679c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
1680ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1681ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara         SourceLocation StartLoc, SourceLocation IdLoc,
1682c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1683c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
1684910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         const TemplateArgument *Args,
1685910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         unsigned NumArgs,
1686d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall         const TemplateArgumentListInfo &ArgInfos,
16873cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall         QualType CanonInjectedType,
168837fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith         ClassTemplatePartialSpecializationDecl *PrevDecl);
1689c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
169094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  static ClassTemplatePartialSpecializationDecl *
16911e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  CreateDeserialized(ASTContext &C, unsigned ID);
169294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1693ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
1694cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplatePartialSpecializationDecl>(
16952dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<ClassTemplateSpecializationDecl *>(
16962dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman               this)->getMostRecentDecl());
1697cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1698cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1699c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1700c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1701c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1702c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1703c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1704833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the template arguments as written.
1705c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
1706833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return ArgsAsWritten;
1707833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1708833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1709ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the member class template partial specialization from
1710ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// which this particular class template partial specialization was
1711ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// instantiated.
1712ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1713ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1714ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1715ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct Outer {
1716ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1717ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*> { }; // #1
1718ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1719ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1720ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// Outer<float>::Inner<int*> ii;
1721ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1722ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1723ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
1724ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// end up instantiating the partial specialization
1725ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
1726ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// template partial specialization \c Outer<T>::Inner<U*>. Given
1727ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, this function would return
1728ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<T>::Inner<U*>.
1729ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
1730bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    ClassTemplatePartialSpecializationDecl *First =
1731bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1732ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getPointer();
1733ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1734ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1735ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setInstantiatedFromMember(
1736ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
1737bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    ClassTemplatePartialSpecializationDecl *First =
1738bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1739ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    First->InstantiatedFromMember.setPointer(PartialSpec);
1740ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1741ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1742ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Determines whether this class template partial specialization
1743ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template was a specialization of a member partial specialization.
1744ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1745ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In the following example, the member template partial specialization
1746ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c X<int>::Inner<T*> is a member specialization.
1747ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1748ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1749ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1750ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X {
1751ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1752ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*>;
1753ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1754ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1755ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<> template<typename T>
1756ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X<int>::Inner<T*> { /* ... */ };
1757ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1758ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  bool isMemberSpecialization() {
1759bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    ClassTemplatePartialSpecializationDecl *First =
1760bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1761ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getInt();
1762ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1763ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1764ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Note that this member template is a specialization.
1765ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setMemberSpecialization() {
1766bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    ClassTemplatePartialSpecializationDecl *First =
1767bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1768ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    assert(First->InstantiatedFromMember.getPointer() &&
1769ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor           "Only member templates can be member template specializations");
1770ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.setInt(true);
1771ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
177231f17ecbef57b5679c017c375db330546b7b5145John McCall
177331f17ecbef57b5679c017c375db330546b7b5145John McCall  /// Retrieves the injected specialization type for this partial
177431f17ecbef57b5679c017c375db330546b7b5145John McCall  /// specialization.  This is not the same as the type-decl-type for
177531f17ecbef57b5679c017c375db330546b7b5145John McCall  /// this partial specialization, which is an InjectedClassNameType.
177631f17ecbef57b5679c017c375db330546b7b5145John McCall  QualType getInjectedSpecializationType() const {
177731f17ecbef57b5679c017c375db330546b7b5145John McCall    assert(getTypeForDecl() && "partial specialization has no type set!");
177831f17ecbef57b5679c017c375db330546b7b5145John McCall    return cast<InjectedClassNameType>(getTypeForDecl())
177931f17ecbef57b5679c017c375db330546b7b5145John McCall             ->getInjectedSpecializationType();
178031f17ecbef57b5679c017c375db330546b7b5145John McCall  }
1781ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1782c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1783c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
178480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
178580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
178680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall    return K == ClassTemplatePartialSpecialization;
1787c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1788c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
17898fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclReader;
17908fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclWriter;
17913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
17923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
17933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
17947c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass ClassTemplateDecl : public RedeclarableTemplateDecl {
17950054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  static void DeallocateCommon(void *Ptr);
1796ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
17973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
17985953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
17995953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
18009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
1801c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    Common() : LazySpecializations() { }
1802ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
18035953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
18045953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
1805d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
18067da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1807c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1808c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
1809d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
1810c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1811c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
18127da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
18137da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1814ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1815c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// \brief If non-null, points to an array of specializations (including
18166982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// partial specializations) known only by their external declaration IDs.
1817c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    ///
1818c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// The first value in the array is the number of of specializations/
1819c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// partial specializations that follow.
1820c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    uint32_t *LazySpecializations;
18215953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
18225953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1823c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  /// \brief Load any lazily-loaded specializations from the external source.
1824e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  void LoadLazySpecializations() const;
1825ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1826cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of specializations of this class template.
1827e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
1828e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  getSpecializations() const;
1829cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1830cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of partial specializations of this class
1831cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// template.
1832d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
1833c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  getPartialSpecializations();
1834cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
18353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
18368731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis                    TemplateParameterList *Params, NamedDecl *Decl)
18379eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
18389eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18399a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  ClassTemplateDecl(EmptyShell Empty)
18409a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor    : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
18419a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor                               DeclarationName(), 0, 0) { }
18429a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
1843b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  CommonBase *newCommon(ASTContext &C) const;
18449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1845e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  Common *getCommonPtr() const {
18469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
18479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18483e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
18493e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
1850d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Get the underlying class declarations of the template.
18513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
18523e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
18533e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
18543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1855d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Returns whether this template declaration defines the primary
185613fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// class pattern.
185713fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
185813fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
185913fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
186013fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
1861d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Create a class template node.
18623e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
18633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
18643e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
18653e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
18665953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
18675953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
18683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1869d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Create an empty class template node.
18701e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
18719a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
1872cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the specialization with the provided arguments if it exists,
1873cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// otherwise return the insertion point.
1874cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplateSpecializationDecl *
1875cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1876cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                     void *&InsertPos);
1877cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1878cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified specialization knowing that it is not already
1879cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// in. InsertPos must be obtained from findSpecialization.
1880bef1a7b9c175d37e4a727e6ce68bd05232fa6970Argyrios Kyrtzidis  void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
18813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
18829eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getCanonicalDecl() {
18837c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<ClassTemplateDecl>(
18847c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
18859eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18869eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const ClassTemplateDecl *getCanonicalDecl() const {
18877c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<ClassTemplateDecl>(
18887c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
18899eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18909eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18919eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
18929eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
1893ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  ClassTemplateDecl *getPreviousDecl() {
18947c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<ClassTemplateDecl>(
18952dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
18969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18979eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18989eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
18999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
1900ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  const ClassTemplateDecl *getPreviousDecl() const {
19017c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<ClassTemplateDecl>(
19022dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<const RedeclarableTemplateDecl *>(
19032dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman               this)->getPreviousDecl());
19049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
19059eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1906daaabf72e77757d62bc9584927dee22968669514Rafael Espindola  ClassTemplateDecl *getMostRecentDecl() {
1907daaabf72e77757d62bc9584927dee22968669514Rafael Espindola    return cast<ClassTemplateDecl>(
19082dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman        static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
1909daaabf72e77757d62bc9584927dee22968669514Rafael Espindola  }
1910daaabf72e77757d62bc9584927dee22968669514Rafael Espindola  const ClassTemplateDecl *getMostRecentDecl() const {
1911daaabf72e77757d62bc9584927dee22968669514Rafael Espindola    return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
1912daaabf72e77757d62bc9584927dee22968669514Rafael Espindola  }
1913daaabf72e77757d62bc9584927dee22968669514Rafael Espindola
19149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
19157c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<ClassTemplateDecl>(
19167c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
19179eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
19189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1919cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the partial specialization with the provided arguments if it
1920cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// exists, otherwise return the insertion point.
1921cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1922cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1923cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                            void *&InsertPos);
1924cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1925cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified partial specialization knowing that it is not
1926cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// already in. InsertPos must be obtained from findPartialSpecialization.
1927cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
1928bef1a7b9c175d37e4a727e6ce68bd05232fa6970Argyrios Kyrtzidis                                void *InsertPos);
1929cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1930dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Retrieve the partial specializations as an ordered list.
1931dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  void getPartialSpecializations(
1932686775deca8b8685eb90801495880e3abdd844c2Chris Lattner          SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
1933ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1934b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1935b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1936b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1937cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param T a dependent type that names a specialization of this class
1938b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1939b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1940b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1941b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1942b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
1943ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1944cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Find a class template partial specialization which was instantiated
1945cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization.
1946cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1947cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param D a member class template partial specialization.
1948cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1949cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \returns the class template partial specialization which was instantiated
1950cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization, or NULL if no such partial
1951cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// specialization exists.
1952cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1953cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findPartialSpecInstantiatedFromMember(
1954cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                                     ClassTemplatePartialSpecializationDecl *D);
19551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19563cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Retrieve the template specialization type of the
19573cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// injected-class-name for this class template.
19587da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
19597da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
19607da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
19617da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
19627da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
19637da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
19647da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
19657da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
19667da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
19677da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
19687da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
19697da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
197024bae92f08ae098cc50a602d8cf1273b423e14daDouglas Gregor  QualType getInjectedClassNameSpecialization();
19717da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
19729f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
19739f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
1974e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_begin() const {
19759f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
19769f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19779f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
1978e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_end() const {
19799f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
19809f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19819f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19829f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
19839f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne          partial_spec_iterator;
19849f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19859f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  partial_spec_iterator partial_spec_begin() {
19869f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getPartialSpecializations(), false);
19879f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19889f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19899f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  partial_spec_iterator partial_spec_end() {
19909f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getPartialSpecializations(), true);
19919f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19929f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
199480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
199580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ClassTemplate; }
19965953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1997d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
19983397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
19993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
20003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
2001d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of a friend template.
2002dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///
2003d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// For example:
2004d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
2005d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// template \<typename T> class A {
2006dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   friend class MyVector<T>; // not a friend template
2007d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<typename U> friend class B; // not a friend template
2008d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<typename U> friend class Foo<T>::Nested; // friend template
2009c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// };
2010d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
2011d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
2012d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \note This class is not currently in use.  All of the above
2013c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// will yield a FriendDecl, not a FriendTemplateDecl.
2014dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallclass FriendTemplateDecl : public Decl {
201599ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
2016dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
201732f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
2018dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2019dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallprivate:
2020dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The number of template parameters;  always non-zero.
2021dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned NumParams;
2022dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2023dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The parameter list.
2024dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList **Params;
2025dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2026dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The declaration that's a friend of this class.
2027dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendUnion Friend;
2028dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2029dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Location of the 'friend' specifier.
2030dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation FriendLoc;
2031dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2032dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2033dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
2034ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                     unsigned NParams,
2035dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     TemplateParameterList **Params,
2036dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     FriendUnion Friend,
2037dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     SourceLocation FriendLoc)
2038dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    : Decl(Decl::FriendTemplate, DC, Loc),
2039dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      NumParams(NParams),
2040dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Params(Params),
2041dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Friend(Friend),
2042dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      FriendLoc(FriendLoc)
2043dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  {}
2044dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2045554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  FriendTemplateDecl(EmptyShell Empty)
2046554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis    : Decl(Decl::FriendTemplate, Empty),
2047554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis      NumParams(0),
2048554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis      Params(0)
2049554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  {}
2050554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2051dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
2052dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static FriendTemplateDecl *Create(ASTContext &Context,
2053dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    DeclContext *DC, SourceLocation Loc,
2054ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                                    unsigned NParams,
2055dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    TemplateParameterList **Params,
2056dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    FriendUnion Friend,
2057dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    SourceLocation FriendLoc);
2058dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
20591e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2060554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2061dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated type (or
2062dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a dependent member type of a templated type), return that
2063dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// type;  otherwise return null.
206432f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  TypeSourceInfo *getFriendType() const {
206532f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return Friend.dyn_cast<TypeSourceInfo*>();
2066dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2067dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2068dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated function (or
2069dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a member function of a templated type), return that type;
2070dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// otherwise return null.
2071dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  NamedDecl *getFriendDecl() const {
2072dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Friend.dyn_cast<NamedDecl*>();
2073dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2074dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2075d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Retrieves the location of the 'friend' keyword.
2076dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation getFriendLoc() const {
2077dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return FriendLoc;
2078dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2079dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2080dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList *getTemplateParameterList(unsigned i) const {
2081dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    assert(i <= NumParams);
2082dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Params[i];
2083dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2084dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2085dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned getNumTemplateParameters() const {
2086dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return NumParams;
2087dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2088dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2089dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Implement isa/cast/dyncast/etc.
209080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
209180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2092554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2093d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
2094dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall};
2095dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2096d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of an alias template.
20973e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith///
2098d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// For example:
2099d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
2100d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
2101d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
21027c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
21033e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static void DeallocateCommon(void *Ptr);
21043e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithprotected:
21063e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  typedef CommonBase Common;
21073e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
21093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                        TemplateParameterList *Params, NamedDecl *Decl)
21103e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
21113e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2112b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  CommonBase *newCommon(ASTContext &C) const;
21133e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21143e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  Common *getCommonPtr() {
21153e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
21163e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21173e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21183e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithpublic:
21193e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// Get the underlying function declaration of the template.
21203e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasDecl *getTemplatedDecl() const {
21213e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return static_cast<TypeAliasDecl*>(TemplatedDecl);
21223e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21233e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21243e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21253e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl *getCanonicalDecl() {
21267c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<TypeAliasTemplateDecl>(
21277c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
21283e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21293e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  const TypeAliasTemplateDecl *getCanonicalDecl() const {
21307c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<TypeAliasTemplateDecl>(
21317c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
21323e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21343e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Retrieve the previous declaration of this function template, or
21353e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// NULL if no such declaration exists.
2136ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  TypeAliasTemplateDecl *getPreviousDecl() {
21377c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<TypeAliasTemplateDecl>(
21382dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
21393e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21403e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21413e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Retrieve the previous declaration of this function template, or
21423e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// NULL if no such declaration exists.
2143ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  const TypeAliasTemplateDecl *getPreviousDecl() const {
21447c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<TypeAliasTemplateDecl>(
21452dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<const RedeclarableTemplateDecl *>(
21462dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman               this)->getPreviousDecl());
21473e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21483e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21493e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
21507c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<TypeAliasTemplateDecl>(
21517c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
21523e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21533e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2154ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
21553e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Create a function template node.
21563e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
21573e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       SourceLocation L,
21583e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       DeclarationName Name,
21593e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       TemplateParameterList *Params,
21603e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       NamedDecl *Decl);
21613e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21623e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Create an empty alias template node.
21631e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
21643e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21653e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  // Implement isa/cast/dyncast support
21663e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
21673e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
21683e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21693e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  friend class ASTDeclReader;
21703e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  friend class ASTDeclWriter;
21713e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith};
21723e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2173d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of a function specialization at template class scope.
2174d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
2175af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// This is a non standard extension needed to support MSVC.
2176d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
2177af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// For example:
2178d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
2179af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// template <class T>
2180af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// class A {
2181af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet///    template <class U> void foo(U a) { }
2182af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet///    template<> void foo(int a) { }
2183af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// }
2184d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
2185af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet///
2186af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// "template<> foo(int a)" will be saved in Specialization as a normal
2187af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// CXXMethodDecl. Then during an instantiation of class A, it will be
2188af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// transformed into an actual function specialization.
2189af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichetclass ClassScopeFunctionSpecializationDecl : public Decl {
219099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
219199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
2192af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
21936b02009359a462ffe633696a4441313b462e6566Nico Weber                                       CXXMethodDecl *FD, bool Args,
21946b02009359a462ffe633696a4441313b462e6566Nico Weber                                       TemplateArgumentListInfo TemplArgs)
2195af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
21966b02009359a462ffe633696a4441313b462e6566Nico Weber      Specialization(FD), HasExplicitTemplateArgs(Args),
21976b02009359a462ffe633696a4441313b462e6566Nico Weber      TemplateArgs(TemplArgs) {}
2198af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2199af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
2200af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
2201af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2202af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  CXXMethodDecl *Specialization;
22036b02009359a462ffe633696a4441313b462e6566Nico Weber  bool HasExplicitTemplateArgs;
22046b02009359a462ffe633696a4441313b462e6566Nico Weber  TemplateArgumentListInfo TemplateArgs;
2205af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2206af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichetpublic:
2207af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  CXXMethodDecl *getSpecialization() const { return Specialization; }
22086b02009359a462ffe633696a4441313b462e6566Nico Weber  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
22096b02009359a462ffe633696a4441313b462e6566Nico Weber  const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
2210af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2211af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
2212af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet                                                      DeclContext *DC,
2213af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet                                                      SourceLocation Loc,
22146b02009359a462ffe633696a4441313b462e6566Nico Weber                                                      CXXMethodDecl *FD,
22156b02009359a462ffe633696a4441313b462e6566Nico Weber                                                   bool HasExplicitTemplateArgs,
22166b02009359a462ffe633696a4441313b462e6566Nico Weber                                        TemplateArgumentListInfo TemplateArgs) {
22176b02009359a462ffe633696a4441313b462e6566Nico Weber    return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD,
22186b02009359a462ffe633696a4441313b462e6566Nico Weber                                                        HasExplicitTemplateArgs,
22196b02009359a462ffe633696a4441313b462e6566Nico Weber                                                        TemplateArgs);
2220af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  }
2221af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
22221e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ClassScopeFunctionSpecializationDecl *
22231e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  CreateDeserialized(ASTContext &Context, unsigned ID);
22241e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
2225af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  // Implement isa/cast/dyncast/etc.
2226af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2227af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  static bool classofKind(Kind K) {
2228af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    return K == Decl::ClassScopeFunctionSpecialization;
2229af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  }
2230af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2231af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  friend class ASTDeclReader;
2232af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  friend class ASTDeclWriter;
2233af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet};
2234af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2235e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
22361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
2237e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
2238e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
2239ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// \brief Represents a variable template specialization, which refers to
2240ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// a variable template with a given set of template arguments.
2241ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo///
2242ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// Variable template specializations represent both explicit
2243ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// specializations of variable templates, as in the example below, and
2244ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// implicit instantiations of variable templates.
2245ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo///
2246ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// \code
2247ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2248ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo///
2249ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// template<>
2250ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// constexpr float pi<float>; // variable template specialization pi<float>
2251ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// \endcode
2252ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplateSpecializationDecl : public VarDecl,
2253ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                      public llvm::FoldingSetNode {
2254ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2255ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Structure that stores information about a variable template
2256ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization that was instantiated from a variable template partial
2257ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization.
2258ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  struct SpecializedPartialSpecialization {
2259ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The variable template partial specialization from which this
2260ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// variable template specialization was instantiated.
2261ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *PartialSpecialization;
2262ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2263ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The template argument list deduced for the variable template
2264ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// partial specialization itself.
2265d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    const TemplateArgumentList *TemplateArgs;
2266ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
2267ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2268ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The template that this specialization specializes.
2269ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2270ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SpecializedTemplate;
2271ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2272ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Further info for explicit template specialization/instantiation.
2273ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  struct ExplicitSpecializationInfo {
2274ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The type-as-written.
2275ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    TypeSourceInfo *TypeAsWritten;
2276ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The location of the extern keyword.
2277ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SourceLocation ExternLoc;
2278ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The location of the template keyword.
2279ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SourceLocation TemplateKeywordLoc;
2280ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2281ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitSpecializationInfo()
2282ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
2283ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
2284ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2285ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Further info for explicit template specialization/instantiation.
2286ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Does not apply to implicit specializations.
2287ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ExplicitSpecializationInfo *ExplicitInfo;
2288ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2289ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The template arguments used to describe this specialization.
2290d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  const TemplateArgumentList *TemplateArgs;
2291ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateArgumentListInfo TemplateArgsInfo;
2292ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2293ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The point where this template was instantiated (if any).
2294ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation PointOfInstantiation;
2295ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2296ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The kind of specialization this declaration refers to.
2297ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Really a value of type TemplateSpecializationKind.
2298ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  unsigned SpecializationKind : 3;
2299ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2300ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoprotected:
2301ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC,
2302ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                SourceLocation StartLoc, SourceLocation IdLoc,
2303ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                VarTemplateDecl *SpecializedTemplate,
2304ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                QualType T, TypeSourceInfo *TInfo,
2305ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                StorageClass S, const TemplateArgument *Args,
2306ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                unsigned NumArgs);
2307ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2308ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  explicit VarTemplateSpecializationDecl(Kind DK);
2309ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2310ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufopublic:
2311ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateSpecializationDecl *
2312ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2313ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2314ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
2315ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         unsigned NumArgs);
2316ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
2317ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                                           unsigned ID);
2318ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2319ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  virtual void getNameForDiagnostic(raw_ostream &OS,
2320ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                    const PrintingPolicy &Policy,
2321ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                    bool Qualified) const;
2322ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2323ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateSpecializationDecl *getMostRecentDecl() {
23242dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman    VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2325ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplateSpecializationDecl>(Recent);
2326ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2327ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2328ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the template that this specialization specializes.
2329ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getSpecializedTemplate() const;
2330ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2331ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the template arguments of the variable template
2332ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization.
2333ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2334ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2335ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  // TODO: Always set this when creating the new specialization?
2336ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
2337ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2338ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const TemplateArgumentListInfo &getTemplateArgsInfo() const {
2339ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return TemplateArgsInfo;
2340ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2341ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2342ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Determine the kind of specialization that this
2343ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// declaration represents.
2344ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateSpecializationKind getSpecializationKind() const {
2345ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return static_cast<TemplateSpecializationKind>(SpecializationKind);
2346ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2347ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2348ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isExplicitSpecialization() const {
2349ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return getSpecializationKind() == TSK_ExplicitSpecialization;
2350ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2351ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2352ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief True if this declaration is an explicit specialization,
2353ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// explicit instantiation declaration, or explicit instantiation
2354ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// definition.
2355ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isExplicitInstantiationOrSpecialization() const {
2356ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    switch (getTemplateSpecializationKind()) {
2357ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ExplicitSpecialization:
2358ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ExplicitInstantiationDeclaration:
2359ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ExplicitInstantiationDefinition:
2360ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return true;
2361ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2362ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_Undeclared:
2363ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ImplicitInstantiation:
2364ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return false;
2365ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    }
2366ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    llvm_unreachable("bad template specialization kind");
2367ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2368ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2369ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setSpecializationKind(TemplateSpecializationKind TSK) {
2370ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializationKind = TSK;
2371ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2372ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2373ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Get the point of instantiation (if any), or null if none.
2374ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation getPointOfInstantiation() const {
2375ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return PointOfInstantiation;
2376ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2377ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2378ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setPointOfInstantiation(SourceLocation Loc) {
2379ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(Loc.isValid() && "point of instantiation must be valid!");
2380ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PointOfInstantiation = Loc;
2381ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2382ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2383ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief If this variable template specialization is an instantiation of
2384ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// a template (rather than an explicit specialization), return the
2385ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template or variable template partial specialization from which
2386ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// it was instantiated.
2387ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2388ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getInstantiatedFrom() const {
2389ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
2390ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
2391ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
2392ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return llvm::PointerUnion<VarTemplateDecl *,
2393ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                VarTemplatePartialSpecializationDecl *>();
2394ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2395ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (SpecializedPartialSpecialization *PartialSpec =
2396ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2397ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return PartialSpec->PartialSpecialization;
2398ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2399ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return SpecializedTemplate.get<VarTemplateDecl *>();
2400ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2401ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2402ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the variable template or variable template partial
2403ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization which was specialized by this.
2404ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2405ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getSpecializedTemplateOrPartial() const {
2406ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (SpecializedPartialSpecialization *PartialSpec =
2407ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2408ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return PartialSpec->PartialSpecialization;
2409ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2410ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return SpecializedTemplate.get<VarTemplateDecl *>();
2411ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2412ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2413ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the set of template arguments that should be used
2414ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// to instantiate the initializer of the variable template or variable
2415ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template partial specialization from which this variable template
2416ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization was instantiated.
2417ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2418ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \returns For a variable template specialization instantiated from the
2419ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// primary template, this function will return the same template arguments
2420ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// as getTemplateArgs(). For a variable template specialization instantiated
2421ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// from a variable template partial specialization, this function will the
2422ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// return deduced template arguments for the variable template partial
2423ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization itself.
2424ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const TemplateArgumentList &getTemplateInstantiationArgs() const {
2425ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (SpecializedPartialSpecialization *PartialSpec =
2426ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2427ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return *PartialSpec->TemplateArgs;
2428ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2429ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return getTemplateArgs();
2430ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2431ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2432ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Note that this variable template specialization is actually an
2433ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiation of the given variable template partial specialization whose
2434ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template arguments have been deduced.
2435ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
2436d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith                          const TemplateArgumentList *TemplateArgs) {
2437ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2438ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           "Already set to a variable template partial specialization!");
2439ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializedPartialSpecialization *PS =
2440ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        new (getASTContext()) SpecializedPartialSpecialization();
2441ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PS->PartialSpecialization = PartialSpec;
2442ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PS->TemplateArgs = TemplateArgs;
2443ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializedTemplate = PS;
2444ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2445ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2446ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Note that this variable template specialization is an instantiation
2447ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// of the given variable template.
2448ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setInstantiationOf(VarTemplateDecl *TemplDecl) {
2449ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2450ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           "Previously set to a variable template partial specialization!");
2451ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializedTemplate = TemplDecl;
2452ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2453ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2454ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Sets the type of this specialization as it was written by
2455ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// the user.
2456ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setTypeAsWritten(TypeSourceInfo *T) {
2457ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (!ExplicitInfo)
2458ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2459ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitInfo->TypeAsWritten = T;
2460ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2461ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Gets the type of this specialization as it was written by
2462ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// the user, if it was so written.
2463ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TypeSourceInfo *getTypeAsWritten() const {
2464ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
2465ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2466ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2467ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Gets the location of the extern keyword, if present.
2468ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation getExternLoc() const {
2469ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2470ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2471ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Sets the location of the extern keyword.
2472ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setExternLoc(SourceLocation Loc) {
2473ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (!ExplicitInfo)
2474ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2475ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitInfo->ExternLoc = Loc;
2476ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2477ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2478ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Sets the location of the template keyword.
2479ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setTemplateKeywordLoc(SourceLocation Loc) {
2480ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (!ExplicitInfo)
2481ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2482ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitInfo->TemplateKeywordLoc = Loc;
2483ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2484ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Gets the location of the template keyword, if present.
2485ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation getTemplateKeywordLoc() const {
2486ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2487ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2488ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2489ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void Profile(llvm::FoldingSetNodeID &ID) const {
2490ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
2491ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2492ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2493ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static void Profile(llvm::FoldingSetNodeID &ID,
2494ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                      const TemplateArgument *TemplateArgs,
2495ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                      unsigned NumTemplateArgs, ASTContext &Context) {
2496ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ID.AddInteger(NumTemplateArgs);
2497ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
2498ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      TemplateArgs[Arg].Profile(ID, Context);
2499ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2500ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2501ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2502ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classofKind(Kind K) {
2503ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return K >= firstVarTemplateSpecialization &&
2504ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           K <= lastVarTemplateSpecialization;
2505ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2506ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2507ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclReader;
2508ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclWriter;
2509ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo};
2510ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2511ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplatePartialSpecializationDecl
2512ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    : public VarTemplateSpecializationDecl {
2513ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  virtual void anchor();
2514ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2515ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The list of template parameters
2516ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateParameterList *TemplateParams;
2517ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2518ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The source info for the template arguments as written.
2519ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// FIXME: redundant with TypeAsWritten?
2520c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *ArgsAsWritten;
2521ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2522ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The variable template partial specialization from which this
2523ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template partial specialization was instantiated.
2524ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2525ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// The boolean value will be true to indicate that this variable template
2526ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// partial specialization was specialized at this level.
2527ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2528ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  InstantiatedFromMember;
2529ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2530ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl(
2531ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2532ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      SourceLocation IdLoc, TemplateParameterList *Params,
2533ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2534ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
253537fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith      const ASTTemplateArgumentListInfo *ArgInfos);
2536ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2537ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl()
2538ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization),
253937fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith        TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {}
2540ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2541ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufopublic:
2542ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplatePartialSpecializationDecl *
2543ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2544ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         SourceLocation IdLoc, TemplateParameterList *Params,
2545ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         VarTemplateDecl *SpecializedTemplate, QualType T,
2546ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
254737fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith         unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
2548ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2549ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
2550ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                                                  unsigned ID);
2551ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2552ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2553ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplatePartialSpecializationDecl>(
25542dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<VarTemplateSpecializationDecl *>(
25552dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman               this)->getMostRecentDecl());
2556ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2557ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2558ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Get the list of template parameters
2559ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateParameterList *getTemplateParameters() const {
2560ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return TemplateParams;
2561ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2562ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2563ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Get the template arguments as written.
2564c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2565ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ArgsAsWritten;
2566ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2567ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2568ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the member variable template partial specialization from
2569ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// which this particular variable template partial specialization was
2570ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiated.
2571ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2572ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \code
2573ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template<typename T>
2574ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// struct Outer {
2575ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U Inner;
2576ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U* Inner<U*> = (U*)(0); // #1
2577ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// };
2578ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2579ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template int* Outer<float>::Inner<int*>;
2580ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \endcode
2581ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2582ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2583ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// end up instantiating the partial specialization
2584ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2585ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2586ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c Outer<float>::Inner<U*>, this function would return
2587ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c Outer<T>::Inner<U*>.
2588ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
2589ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2590bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2591ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return First->InstantiatedFromMember.getPointer();
2592ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2593ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2594ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void
2595ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2596ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2597bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2598ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    First->InstantiatedFromMember.setPointer(PartialSpec);
2599ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2600ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2601ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Determines whether this variable template partial specialization
2602ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// was a specialization of a member partial specialization.
2603ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2604ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// In the following example, the member template partial specialization
2605ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c X<int>::Inner<T*> is a member specialization.
2606ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2607ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \code
2608ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template<typename T>
2609ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// struct X {
2610ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U Inner;
2611ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U* Inner<U*> = (U*)(0);
2612ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// };
2613ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2614ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template<> template<typename T>
2615ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2616ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \endcode
2617ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isMemberSpecialization() {
2618ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2619bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2620ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return First->InstantiatedFromMember.getInt();
2621ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2622ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2623ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Note that this member template is a specialization.
2624ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setMemberSpecialization() {
2625ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2626bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2627ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(First->InstantiatedFromMember.getPointer() &&
2628ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           "Only member templates can be member template specializations");
2629ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return First->InstantiatedFromMember.setInt(true);
2630ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2631ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2632ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2633ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classofKind(Kind K) {
2634ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return K == VarTemplatePartialSpecialization;
2635ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2636ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2637ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclReader;
2638ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclWriter;
2639ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo};
2640ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2641ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// Declaration of a variable template.
2642ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplateDecl : public RedeclarableTemplateDecl {
2643ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static void DeallocateCommon(void *Ptr);
2644ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2645ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoprotected:
2646ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Data that is common to all of the declarations of a given
2647ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template.
2648ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  struct Common : CommonBase {
2649ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    Common() : LazySpecializations() {}
2650ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2651ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The variable template specializations for this variable
2652ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// template, including explicit specializations and instantiations.
2653ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
2654ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2655ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The variable template partial specializations for this variable
2656ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// template.
2657ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
2658ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PartialSpecializations;
2659ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2660ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief If non-null, points to an array of specializations (including
2661ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// partial specializations) known ownly by their external declaration IDs.
2662ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ///
2663ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// The first value in the array is the number of of specializations/
2664ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// partial specializations that follow.
2665ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    uint32_t *LazySpecializations;
2666ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
2667ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2668ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Load any lazily-loaded specializations from the external source.
2669ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void LoadLazySpecializations() const;
2670ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2671ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the set of specializations of this variable template.
2672ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
2673ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getSpecializations() const;
2674ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2675ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the set of partial specializations of this class
2676ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template.
2677ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
2678ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getPartialSpecializations();
2679ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2680ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
2681ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                  TemplateParameterList *Params, NamedDecl *Decl)
2682ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {}
2683ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2684ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl(EmptyShell Empty)
2685ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(),
2686ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                 DeclarationName(), 0, 0) {}
2687ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2688ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  CommonBase *newCommon(ASTContext &C) const;
2689ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2690ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  Common *getCommonPtr() const {
2691ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2692ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2693ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2694ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufopublic:
2695ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Get the underlying variable declarations of the template.
2696ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarDecl *getTemplatedDecl() const {
2697ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return static_cast<VarDecl *>(TemplatedDecl);
2698ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2699ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2700ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Returns whether this template declaration defines the primary
2701ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable pattern.
2702ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isThisDeclarationADefinition() const {
2703ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return getTemplatedDecl()->isThisDeclarationADefinition();
2704ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2705ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2706439d665f4d1066ee5ebd8dd0938d85be83d490c4Larisse Voufo  VarTemplateDecl *getDefinition();
2707439d665f4d1066ee5ebd8dd0938d85be83d490c4Larisse Voufo
2708ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Create a variable template node.
2709ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
2710ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                 SourceLocation L, DeclarationName Name,
2711ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                 TemplateParameterList *Params, NamedDecl *Decl,
2712ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                 VarTemplateDecl *PrevDecl);
2713ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2714ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Create an empty variable template node.
2715ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2716ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2717ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Return the specialization with the provided arguments if it exists,
2718ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// otherwise return the insertion point.
2719ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateSpecializationDecl *
2720ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
2721ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                     void *&InsertPos);
2722ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2723ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Insert the specified specialization knowing that it is not already
2724ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// in. InsertPos must be obtained from findSpecialization.
2725ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
2726ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2727ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getCanonicalDecl() {
2728ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
2729ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2730ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const VarTemplateDecl *getCanonicalDecl() const {
2731ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
2732ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2733ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2734ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the previous declaration of this variable template, or
2735ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// NULL if no such declaration exists.
2736ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getPreviousDecl() {
2737ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast_or_null<VarTemplateDecl>(
27382dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman        static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2739ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2740ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2741ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the previous declaration of this variable template, or
2742ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// NULL if no such declaration exists.
2743ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const VarTemplateDecl *getPreviousDecl() const {
2744ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast_or_null<VarTemplateDecl>(
27452dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman            static_cast<const RedeclarableTemplateDecl *>(
27462dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman              this)->getPreviousDecl());
2747ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2748ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2749ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getInstantiatedFromMemberTemplate() {
2750ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast_or_null<VarTemplateDecl>(
2751ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
2752ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2753ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2754ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Return the partial specialization with the provided arguments if it
2755ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// exists, otherwise return the insertion point.
2756ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *
2757ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
2758ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                            void *&InsertPos);
2759ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2760ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Insert the specified partial specialization knowing that it is not
2761ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// already in. InsertPos must be obtained from findPartialSpecialization.
2762ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
2763ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                void *InsertPos);
2764ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2765ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the partial specializations as an ordered list.
2766ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void getPartialSpecializations(
2767ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
2768ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2769ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Find a variable template partial specialization which was
2770ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiated
2771ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// from the given member partial specialization.
2772ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2773ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \param D a member variable template partial specialization.
2774ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2775ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \returns the variable template partial specialization which was
2776ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiated
2777ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// from the given member partial specialization, or NULL if no such partial
2778ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization exists.
2779ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
2780ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      VarTemplatePartialSpecializationDecl *D);
2781ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2782ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
2783ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2784ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  spec_iterator spec_begin() const {
2785ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getSpecializations(), false);
2786ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2787ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2788ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  spec_iterator spec_end() const {
2789ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getSpecializations(), true);
2790ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2791ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2792ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  typedef SpecIterator<VarTemplatePartialSpecializationDecl>
2793ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  partial_spec_iterator;
2794ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2795ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  partial_spec_iterator partial_spec_begin() {
2796ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getPartialSpecializations(), false);
2797ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2798ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2799ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  partial_spec_iterator partial_spec_end() {
2800ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getPartialSpecializations(), true);
2801ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2802ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2803ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  // Implement isa/cast/dyncast support
2804ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2805ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classofKind(Kind K) { return K == VarTemplate; }
2806ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2807ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclReader;
2808ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclWriter;
2809ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo};
2810ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2811aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
2812aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
2813aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
2814