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
89ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ArrayRef<NamedDecl*> asArray() {
90ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return ArrayRef<NamedDecl*>(begin(), size());
915a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
92ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ArrayRef<const NamedDecl*> asArray() const {
93ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return 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.
206ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ArrayRef<TemplateArgument> asArray() const {
207ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return 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 {
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
231127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // This is probably never used.
233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
234127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name)
2356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
2366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      TemplateParams(nullptr) {}
237d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
238127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with the given name and parameters.
239127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
240127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
241127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
2426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
2436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      TemplateParams(Params) {}
244d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
245127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
246127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
247127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
248127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               NamedDecl *Decl)
249127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
250127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParams(Params) { }
251127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
252127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the list of template parameters
253127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
254127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
255d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
256d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
257127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
258127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
259127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
260aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
26180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
26280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
2639a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstTemplate && K <= lastTemplate;
26480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  }
265aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY {
26780484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor    return SourceRange(TemplateParams->getTemplateLoc(),
26880484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor                       TemplatedDecl->getSourceRange().getEnd());
26980484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor  }
27080484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor
271127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
272127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
273127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
274ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2758731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidispublic:
2768731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Initialize the underlying templated declaration and
2778731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// template parameters.
2788731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
2796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(!TemplatedDecl && "TemplatedDecl already set!");
2806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    assert(!TemplateParams && "TemplateParams already set!");
2818731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplatedDecl = templatedDecl;
2828731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplateParams = templateParams;
2838731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  }
284127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Provides information about a function template specialization,
287127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
288127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
289127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
290a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  FunctionTemplateSpecializationInfo(FunctionDecl *FD,
291a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     FunctionTemplateDecl *Template,
292a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     TemplateSpecializationKind TSK,
293a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     const TemplateArgumentList *TemplateArgs,
29471a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis                       const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
295a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     SourceLocation POI)
296a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  : Function(FD),
297a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    Template(Template, TSK - 1),
298a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArguments(TemplateArgs),
299a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArgumentsAsWritten(TemplateArgsAsWritten),
300a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    PointOfInstantiation(POI) { }
301a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
302127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
303a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  static FunctionTemplateSpecializationInfo *
304a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
305a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         TemplateSpecializationKind TSK,
306a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentList *TemplateArgs,
307a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentListInfo *TemplateArgsAsWritten,
30871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis         SourceLocation POI);
309a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
3101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template specialization that this structure
311127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
312127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template from which this function template
315127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
3161fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
317d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
318d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
3191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
320127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
321127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
322127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
324e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara  /// \brief The template arguments as written in the sources, if provided.
32571a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
326e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara
327b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief The point at which this function template specialization was
328ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// first instantiated.
329b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
330ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3311fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
3321fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
333d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
334d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Determine what kind of template specialization this is.
335d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
336d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    return (TemplateSpecializationKind)(Template.getInt() + 1);
337d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  }
338d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
3396ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  bool isExplicitSpecialization() const {
3406ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
3416ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  }
3426ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall
3435a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// \brief True if this declaration is an explicit specialization,
3445a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// explicit instantiation declaration, or explicit instantiation
3455a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// definition.
3465a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  bool isExplicitInstantiationOrSpecialization() const {
3475a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    switch (getTemplateSpecializationKind()) {
3485a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitSpecialization:
3495a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDeclaration:
3505a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDefinition:
3515a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return true;
3525a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
3535a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_Undeclared:
3545a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ImplicitInstantiation:
3555a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return false;
3565a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    }
3575a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    llvm_unreachable("bad template specialization kind");
3585a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
3595a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
360d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Set the template specialization kind.
361d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(TSK != TSK_Undeclared &&
363d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor         "Cannot encode TSK_Undeclared for a function template specialization");
364d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    Template.setInt(TSK - 1);
3651fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
3661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
367b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this function
368b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// template specialization.
369b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  ///
370b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// The point of instantiation may be an invalid source location if this
371b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// function has yet to be instantiated.
372ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getPointOfInstantiation() const {
373ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    return PointOfInstantiation;
374b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
375ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
376b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the (first) point of instantiation of this function template
377b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// specialization.
378b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
379b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
380b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
381ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
382127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
383ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Profile(ID, TemplateArguments->asArray(),
3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Function->getASTContext());
385127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
388ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
389ef8225444452a1486bd721f3285301fe84643b00Stephen Hines          ASTContext &Context) {
390ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ID.AddInteger(TemplateArgs.size());
391ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
392828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
394127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
396ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// \brief Provides information a specialization of a member of a class
397f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith/// template, which may be a member function, static data member,
398f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith/// member class or member enumeration.
3992db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorclass MemberSpecializationInfo {
40044e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // The member declaration from which this member was instantiated, and the
40144e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // manner in which the instantiation occurred (in the lower two bits).
40244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
403ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
404b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  // The point at which this member was first instantiated.
405b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
406ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4072db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorpublic:
408ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  explicit
4099421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
4109421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis                           SourceLocation POI = SourceLocation())
4119421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
412ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    assert(TSK != TSK_Undeclared &&
41344e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
41444e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  }
415ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4162db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Retrieve the member declaration from which this member was
4172db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// instantiated.
41844e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
419ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4202db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Determine what kind of template specialization this is.
4212db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
42244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
4232db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
424ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4253892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall  bool isExplicitSpecialization() const {
4263892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
4273892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall  }
4283892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall
4292db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Set the template specialization kind.
4302db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
431ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    assert(TSK != TSK_Undeclared &&
43244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
43344e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    MemberAndTSK.setInt(TSK - 1);
4342db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
435ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
436ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieve the first point of instantiation of this member.
437b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// If the point of instantiation is an invalid location, then this member
438b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// has not yet been instantiated.
439ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getPointOfInstantiation() const {
440ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    return PointOfInstantiation;
441b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
442ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
443b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the first point of instantiation.
444b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
445b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
446b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
4472db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor};
448af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
449af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// \brief Provides information about a dependent function-template
450d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// specialization declaration.
451d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
452d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// Since explicit function template specialization and instantiation
453d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// declarations can only appear in namespace scope, and you can only
454d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// specialize a member of a fully-specialized class, the only way to
455d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// get one of these is in a friend declaration like the following:
456af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///
457d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
458d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<class T> void foo(T);
459d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<class T> class A {
460af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///     friend void foo<>(T);
461af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   };
462d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
463af2094e7cecadf36667deb61a83587ffdd979bd3John McCallclass DependentFunctionTemplateSpecializationInfo {
464e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct CA {
465e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    /// The number of potential template candidates.
466e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned NumTemplates;
467e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
468e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    /// The number of template arguments.
469e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned NumArgs;
470e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
471e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
472af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  union {
473af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // Force sizeof to be a multiple of sizeof(void*) so that the
474af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // trailing data is aligned.
475ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    void *Aligner;
476e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct CA d;
477af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  };
478af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
479af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// The locations of the left and right angle brackets.
480af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceRange AngleLocs;
481af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
482af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl * const *getTemplates() const {
483af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
484af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
485af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
486af2094e7cecadf36667deb61a83587ffdd979bd3John McCallpublic:
487af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  DependentFunctionTemplateSpecializationInfo(
488af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const UnresolvedSetImpl &Templates,
489af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const TemplateArgumentListInfo &TemplateArgs);
490af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
491af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of function templates that this might
492af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// be a specialization of.
493af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplates() const {
494af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumTemplates;
495af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
496af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
497af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the i'th template candidate.
498af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl *getTemplate(unsigned I) const {
499af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplates() && "template index out of range");
500af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplates()[I];
501af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
502af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
503e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  /// \brief Returns the explicit template arguments that were given.
504e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  const TemplateArgumentLoc *getTemplateArgs() const {
505e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor    return reinterpret_cast<const TemplateArgumentLoc*>(
506ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                                            &getTemplates()[getNumTemplates()]);
507e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  }
508e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor
509af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of explicit template arguments that were given.
510af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplateArgs() const {
511af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumArgs;
512af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
513af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
514af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the nth template argument.
515af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
516af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplateArgs() && "template arg index out of range");
517af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplateArgs()[I];
518af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
519af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
520af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getLAngleLoc() const {
521af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getBegin();
522af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
523af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
524af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getRAngleLoc() const {
525af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getEnd();
526af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
527af2094e7cecadf36667deb61a83587ffdd979bd3John McCall};
528ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
5299eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a redeclarable template.
5307c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass RedeclarableTemplateDecl : public TemplateDecl,
5317c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor                                 public Redeclarable<RedeclarableTemplateDecl>
5327c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor{
5337c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
5346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
5356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return getNextRedeclaration();
5369eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
537651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  RedeclarableTemplateDecl *getPreviousDeclImpl() override {
538ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getPreviousDecl();
539ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
541ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getMostRecentDecl();
542ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
5431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
54544dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  template <typename EntryType> struct SpecEntryTraits {
54644dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    typedef EntryType DeclType;
54744dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
548ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    static DeclType *getMostRecentDecl(EntryType *D) {
549ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      return D->getMostRecentDecl();
55044dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    }
55144dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  };
55244dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
5539f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType,
5549f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _SETraits = SpecEntryTraits<EntryType>,
5559f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _DeclType = typename _SETraits::DeclType>
5569f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  class SpecIterator : public std::iterator<std::forward_iterator_tag,
5579f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, ptrdiff_t,
5589f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, _DeclType*> {
5599f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _SETraits SETraits;
5609f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _DeclType DeclType;
5619f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
562d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    typedef typename llvm::FoldingSetVector<EntryType>::iterator
563d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth      SetIteratorType;
5649f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5659f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SetIteratorType SetIter;
5669f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5679f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  public:
5689f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator() : SetIter() {}
5699f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
5709f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5719f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator*() const {
572ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      return SETraits::getMostRecentDecl(&*SetIter);
5739f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5749f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator->() const { return **this; }
5759f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5769f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator &operator++() { ++SetIter; return *this; }
5779f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator operator++(int) {
5789f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      SpecIterator tmp(*this);
5799f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      ++(*this);
5809f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return tmp;
5819f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5829f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5839f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator==(SpecIterator Other) const {
5849f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter == Other.SetIter;
5859f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5869f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator!=(SpecIterator Other) const {
5879f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter != Other.SetIter;
5889f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5899f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  };
5909f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5919f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType>
592e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  static SpecIterator<EntryType>
593d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
5949f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
5959f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
5969f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5974048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne  template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
598d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
599ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                         ArrayRef<TemplateArgument> Args, void *&InsertPos);
6004048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne
6019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct CommonBase {
6026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    CommonBase() : InstantiatedFromMember(nullptr, 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.
6256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
6266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                           SourceLocation L, DeclarationName Name,
6276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                           TemplateParameterList *Params, NamedDecl *Decl)
6286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
6296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        Common() {}
6301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
6329eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  template <class decl_type> friend class RedeclarableTemplate;
6339eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
634d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Retrieves the canonical declaration of this template.
635651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  RedeclarableTemplateDecl *getCanonicalDecl() override {
636651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return getFirstDecl();
637651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
638bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola  const RedeclarableTemplateDecl *getCanonicalDecl() const {
639bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    return getFirstDecl();
640ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
641ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
642ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Determines whether this template was a specialization of a
6439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// member template.
6449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// In the following example, the function template \c X<int>::f and the
6469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// member template \c X<int>::Inner are member specializations.
6479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \code
6499eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<typename T>
6509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// struct X {
6519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template<typename U> void f(T, U);
6529eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template<typename U> struct Inner;
6539eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// };
6549eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6559eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<> template<typename T>
6569eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// void X<int>::f(int, T);
6579eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<> template<typename T>
6589eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// struct X<int>::Inner { /* ... */ };
6599eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \endcode
660b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  bool isMemberSpecialization() const {
6619eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCommonPtr()->InstantiatedFromMember.getInt();
6629eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
663ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
6649eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Note that this member template is a specialization.
6659eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setMemberSpecialization() {
6669eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
6679eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne           "Only member templates can be member template specializations");
6689eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    getCommonPtr()->InstantiatedFromMember.setInt(true);
6699eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
670ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
6710f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \brief Retrieve the member template from which this template was
6720f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// instantiated, or NULL if this template was not instantiated from a
6730f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// member template.
6740f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6750f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// A template is instantiated from a member template when the member
6760f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template itself is part of a class template (or member thereof). For
6770f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// example, given
6780f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6790f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \code
6800f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename T>
6810f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// struct X {
6820f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///   template<typename U> void f(T, U);
6830f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// };
6840f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6850f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// void test(X<int> x) {
6860f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///   x.f(1, 'a');
6870f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// };
6880f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \endcode
6890f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6900f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \c X<int>::f is a FunctionTemplateDecl that describes the function
6910f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template
6920f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6930f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \code
6940f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename U> void X<int>::f(int, U);
6950f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \endcode
6960f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6970f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// which was itself created during the instantiation of \c X<int>. Calling
6980f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
699d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// retrieve the FunctionTemplateDecl for the original template \c f within
7000f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// the class template \c X<T>, i.e.,
7010f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
7020f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \code
7030f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename T>
7040f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename U>
7050f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// void X<T>::f(T, U);
7060f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \endcode
707b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
7087c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return getCommonPtr()->InstantiatedFromMember.getPointer();
7097c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  }
7107c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor
7117c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
7127c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
7137c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    getCommonPtr()->InstantiatedFromMember.setPointer(TD);
7149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7159eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef redeclarable_base::redecl_range redecl_range;
717a54fbf2499c7cc999e22abb9be484ce976ed9689Douglas Gregor  typedef redeclarable_base::redecl_iterator redecl_iterator;
718ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_begin;
719ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_end;
720651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  using redeclarable_base::redecls;
721ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getPreviousDecl;
722ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getMostRecentDecl;
7237693b32af6863c63fcaf4de087760740ee675f71Rafael Espindola  using redeclarable_base::isFirstDecl;
724f785a7d611404cf4747287a2bbc59b4d0e6a5a8cDouglas Gregor
7259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  // Implement isa/cast/dyncast/etc.
7269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
7279eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classofKind(Kind K) {
7289eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
7299eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7309eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7317c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  friend class ASTReader;
732d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
7333397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
7349eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne};
7359eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
73644dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbournetemplate <> struct RedeclarableTemplateDecl::
73744dd0b440efdb37ff4c6e49f243faa3b0580b120Peter CollingbourneSpecEntryTraits<FunctionTemplateSpecializationInfo> {
73844dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  typedef FunctionDecl DeclType;
73944dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
74044dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  static DeclType *
741ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  getMostRecentDecl(FunctionTemplateSpecializationInfo *I) {
742ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return I->Function->getMostRecentDecl();
74344dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  }
74444dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne};
74544dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
7469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a template function.
7477c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass FunctionTemplateDecl : public RedeclarableTemplateDecl {
7489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static void DeallocateCommon(void *Ptr);
7499eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
7519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Data that is common to all of the declarations of a given
7529eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
7539eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
7546982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    Common() : InjectedArgs(), LazySpecializations() { }
755ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
7569eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// \brief The function template specializations for this function
7579eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// template, including explicit specializations and instantiations.
758d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
759ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
760c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// \brief The set of "injected" template arguments used within this
761c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// function template.
762c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    ///
763c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// This pointer refers to the template arguments (there are as
764c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// many template arguments as template parameaters) for the function
765c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// template, and is allocated lazily, since most function templates do not
766c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// require the use of this information.
767c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    TemplateArgument *InjectedArgs;
7686982bf4d77bc57a85ee173b631729fce673f16efRichard Smith
7696982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// \brief If non-null, points to an array of specializations known only
7706982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// by their external declaration IDs.
7716982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    ///
7726982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// The first value in the array is the number of of specializations
7736982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// that follow.
7746982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    uint32_t *LazySpecializations;
7759eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  };
7769eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
7786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                       DeclarationName Name, TemplateParameterList *Params,
7796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                       NamedDecl *Decl)
7806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
7816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                 Decl) {}
7829eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
783651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CommonBase *newCommon(ASTContext &C) const override;
7849eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
785e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  Common *getCommonPtr() const {
7869eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
787fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
7889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7896b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  friend class FunctionDecl;
790da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor
7916982bf4d77bc57a85ee173b631729fce673f16efRichard Smith  /// \brief Load any lazily-loaded specializations from the external source.
7926982bf4d77bc57a85ee173b631729fce673f16efRichard Smith  void LoadLazySpecializations() const;
7936982bf4d77bc57a85ee173b631729fce673f16efRichard Smith
7949eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the set of function template specializations of this
7959eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
796d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
7976982bf4d77bc57a85ee173b631729fce673f16efRichard Smith  getSpecializations() const;
7985bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl
7995bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  /// \brief Add a specialization of this function template.
8005bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  ///
801d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  /// \param InsertPos Insert position in the FoldingSetVector, must have been
8025bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  ///        retrieved by an earlier call to findSpecialization().
8035bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  void addSpecialization(FunctionTemplateSpecializationInfo* Info,
8045bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl                         void *InsertPos);
805ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
8069eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbournepublic:
8079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// Get the underlying function declaration of the template.
8089eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionDecl *getTemplatedDecl() const {
8099eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<FunctionDecl*>(TemplatedDecl);
8109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
81213fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// Returns whether this template declaration defines the primary
81313fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// pattern.
81413fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
81513fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
81613fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
81713fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
8189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Return the specialization with the provided arguments if it exists,
8199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// otherwise return the insertion point.
820ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
821ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                                   void *&InsertPos);
8229eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
823651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  FunctionTemplateDecl *getCanonicalDecl() override {
8247c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<FunctionTemplateDecl>(
8257c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
8269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8279eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const FunctionTemplateDecl *getCanonicalDecl() const {
8287c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<FunctionTemplateDecl>(
8297c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
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  FunctionTemplateDecl *getPreviousDecl() {
8357c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<FunctionTemplateDecl>(
8362dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
8379eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8389eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8399eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this function template, or
8409eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
841ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  const FunctionTemplateDecl *getPreviousDecl() const {
8427c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<FunctionTemplateDecl>(
8432dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman       static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
8449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
8477c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<FunctionTemplateDecl>(
8487c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
8499eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8519f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
852651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<spec_iterator> spec_range;
8539f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
854651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  spec_range specializations() const {
855651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return spec_range(spec_begin(), spec_end());
856651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
857e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_begin() const {
8589f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
8599f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8609f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
861e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_end() const {
8629f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
8639f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8649f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
865c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// \brief Retrieve the "injected" template arguments that correspond to the
866c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// template parameters of this function template.
867ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ///
868c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// Although the C++ standard has no notion of the "injected" template
869c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// arguments for a function template, the notion is convenient when
870c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// we need to perform substitutions inside the definition of a function
871ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// template.
8727a9f7c7c68673c46d6e2b83fec6f4cbfbd25f475Richard Smith  ArrayRef<TemplateArgument> getInjectedTemplateArgs();
873ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
8749a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  /// \brief Create a function template node.
875127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
876127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
877127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
878127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
879127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
8803e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
8819a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  /// \brief Create an empty function template node.
8821e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
8839a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
884127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
88580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
88680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == FunctionTemplate; }
887c8f9af2943699ff623ca08f2e5ed4d72e0351189Argyrios Kyrtzidis
888d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
8893397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
890127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
891d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
892127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
893127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
894127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
89540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
896d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Defines the position of a template parameter within a template
897d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// parameter list.
898d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
899d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// Because template parameter can be listed
900127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
901127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
902127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
903127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
904127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
9051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass TemplateParmPosition {
906651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  TemplateParmPosition() LLVM_DELETED_FUNCTION;
9073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
908651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesprotected:
909127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
910127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
911127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
9123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
913127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
914127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
915127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
916127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
9173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
918127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
919127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
920127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
921b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setDepth(unsigned D) { Depth = D; }
9223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
923127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
924127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
925b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setPosition(unsigned P) { Position = P; }
9261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
927127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
928127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
929127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
9303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
931d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of a template type parameter.
932d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
933d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// For example, "T" in
934d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
935127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
936d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
937127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
938127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
939d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// the 'typename' keyword.
940d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  ///
941d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// If false, it was declared with the 'class' keyword.
942127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
9433e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
944127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
945127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
946127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
9473e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
948127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
949a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *DefaultArgument;
950127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
951344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara  TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
952344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                       SourceLocation IdLoc, IdentifierInfo *Id,
9534fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth                       bool Typename)
954344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara    : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
9554fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth      InheritedDefault(false), DefaultArgument() { }
9563e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
957483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  /// Sema creates these on the stack during auto type deduction.
958483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  friend class Sema;
959483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
960127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
9614ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
962344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      SourceLocation KeyLoc,
963344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      SourceLocation NameLoc,
964344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      unsigned D, unsigned P,
965127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
966127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
9671e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
9681e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                  unsigned ID);
969c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
970127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
971d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// the 'typename' keyword.
972d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  ///
973d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// If not, it was declared with the 'class' keyword.
974127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
975c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
976127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
977127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
9786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool hasDefaultArgument() const { return DefaultArgument != nullptr; }
979199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
980127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
981833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
98240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
983833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the default argument's source information, if any.
984a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
985833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
986833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the location of the default argument declaration.
987833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  SourceLocation getDefaultArgumentLoc() const;
98840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
989127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
990127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
991127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
992f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
993127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
994127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
995127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
996a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
997127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
998127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
999f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
100040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
1001833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Removes the default argument of this template parameter.
1002833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  void removeDefaultArgument() {
10036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DefaultArgument = nullptr;
1004833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    InheritedDefault = false;
1005833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1006ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
10078731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Set whether this template type parameter was declared with
10088731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// the 'typename' or 'class' keyword.
10098731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
10108731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
1011ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the depth of the template parameter.
1012ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
1013ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1014ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the index of the template parameter.
1015ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getIndex() const;
1016ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1017127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
10184fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth  bool isParameterPack() const;
1019fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
1020651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY;
102177d4ee2bfc90b77ec8b818de985cd4aceeef757bAbramo Bagnara
1022127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
102380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
102480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
10253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
10263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1027127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1028127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
1029127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1030127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
1031127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1032127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
103376a40219ee5624d78aba167dce02bdbaa930955fJohn McCall  : public DeclaratorDecl, protected TemplateParmPosition {
1034d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief The default template argument, if any, and whether or not
1035d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// it was inherited.
1036d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
1037127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
103810738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
103910738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  // down here to save memory.
1040ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
104110738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \brief Whether this non-type template parameter is a parameter pack.
104210738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  bool ParameterPack;
1043ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1044ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Whether this non-type template parameter is an "expanded"
10456952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// parameter pack, meaning that its type is a pack expansion and we
10466952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// already know the set of types that expansion expands to.
10476952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  bool ExpandedParameterPack;
1048ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
10496952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief The number of types in an expanded parameter pack.
10506952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  unsigned NumExpandedTypes;
1051ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1052ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1053ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          SourceLocation IdLoc, unsigned D, unsigned P,
1054ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          IdentifierInfo *Id, QualType T,
105510738d36b150aa65206890c1c845cdba076e4200Douglas Gregor                          bool ParameterPack, TypeSourceInfo *TInfo)
1056ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
10576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
10586952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      ParameterPack(ParameterPack), ExpandedParameterPack(false),
10596952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      NumExpandedTypes(0)
1060127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
1061127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1062ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1063ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          SourceLocation IdLoc, unsigned D, unsigned P,
1064ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          IdentifierInfo *Id, QualType T,
10656952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          TypeSourceInfo *TInfo,
10666952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          const QualType *ExpandedTypes,
10676952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          unsigned NumExpandedTypes,
10686952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          TypeSourceInfo **ExpandedTInfos);
10696952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
107010738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  friend class ASTDeclReader;
1071ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
10721c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
1073127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
1074ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1075ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1076ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
10779ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
10786952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  static NonTypeTemplateParmDecl *
1079ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1080ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1081ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         QualType T, TypeSourceInfo *TInfo,
10826952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor         const QualType *ExpandedTypes, unsigned NumExpandedTypes,
10836952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor         TypeSourceInfo **ExpandedTInfos);
10846952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
10851e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
10861e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned ID);
10871e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
10881e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned ID,
10891e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned NumExpandedTypes);
10901e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1091127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1092b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setDepth;
1093127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1094b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setPosition;
1095127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
10961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1097651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY;
109876a40219ee5624d78aba167dce02bdbaa930955fJohn McCall
1099127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1100127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1101d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
11026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return DefaultArgumentAndInherited.getPointer() != nullptr;
1103d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1104fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
1105127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1106d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  Expr *getDefaultArgument() const {
1107d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer();
1108d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1109127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1110127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
1111127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
1112127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1113d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1114d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1115d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1116d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getInt();
1117d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1118d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1119d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1120d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1121d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1122d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(Expr *DefArg, bool Inherited) {
1123d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(DefArg);
1124d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(Inherited);
1125d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1126d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1127d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1128d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
11296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DefaultArgumentAndInherited.setPointer(nullptr);
1130d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(false);
11313b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
1132127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
113310738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \brief Whether this parameter is a non-type template parameter pack.
113410738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  ///
113510738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// If the parameter is a parameter pack, the type may be a
113610738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \c PackExpansionType. In the following example, the \c Dims parameter
113710738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// is a parameter pack (whose type is 'unsigned').
113810738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  ///
113910738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \code
114010738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// template<typename T, unsigned ...Dims> struct multi_array;
114110738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \endcode
114210738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  bool isParameterPack() const { return ParameterPack; }
1143ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
11446964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this parameter pack is a pack expansion.
11456964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
11466964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// A non-type template parameter pack is a pack expansion if its type
11476964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// contains an unexpanded parameter pack. In this case, we will have
11486964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// built a PackExpansionType wrapping the type.
11496964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool isPackExpansion() const {
11506964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return ParameterPack && getType()->getAs<PackExpansionType>();
11516964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
11526964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
11536952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief Whether this parameter is a non-type template parameter pack
11546964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// that has a known list of different types at different positions.
11556952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11566952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// A parameter pack is an expanded parameter pack when the original
11576952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// parameter pack's type was itself a pack expansion, and that expansion
11586952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// has already been expanded. For example, given:
11596952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11606952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \code
11616952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// template<typename ...Types>
11626952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// struct X {
11636952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///   template<Types ...Values>
11646952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///   struct Y { /* ... */ };
11656952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// };
11666952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \endcode
1167ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ///
11686952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// The parameter pack \c Values has a \c PackExpansionType as its type,
11696952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// which expands \c Types. When \c Types is supplied with template arguments
1170ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// by instantiating \c X, the instantiation of \c Values becomes an
1171ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// expanded parameter pack. For example, instantiating
11726952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \c X<int, unsigned int> results in \c Values being an expanded parameter
11736952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// pack with expansion types \c int and \c unsigned int.
11746952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
1175ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
11766952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// return the expansion types.
11776952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1178ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1179ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieves the number of expansion types in an expanded parameter
1180ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// pack.
11816952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  unsigned getNumExpansionTypes() const {
11826952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(ExpandedParameterPack && "Not an expansion parameter pack");
11836952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return NumExpandedTypes;
11846952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11856952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1186ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieve a particular expansion type within an expanded parameter
11876952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// pack.
11886952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  QualType getExpansionType(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 QualType::getFromOpaquePtr(TypesAndInfos[2*I]);
11926952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11936952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1194ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieve a particular expansion type source info within an
11956952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// expanded parameter pack.
11966952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
11976952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
11986952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
11996952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]);
12006952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
12016952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
120380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
120480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
12051c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
12061c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
1207127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
1208127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
1209127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1210127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
1211127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1212127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
1213127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
12141e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregorclass TemplateTemplateParmDecl : public TemplateDecl,
12151e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                 protected TemplateParmPosition
12161e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor{
1217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
12187e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1219d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// DefaultArgument - The default template argument, if any.
1220788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  TemplateArgumentLoc DefaultArgument;
1221d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// Whether or not the default argument was inherited.
1222d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool DefaultArgumentWasInherited;
12237e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
122461c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  /// \brief Whether this parameter is a parameter pack.
122561c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  bool ParameterPack;
1226ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
12276964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this template template parameter is an "expanded"
12286964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// parameter pack, meaning that it is a pack expansion and we
12296964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// already know the set of template parameters that expansion expands to.
12306964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool ExpandedParameterPack;
12316964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
12326964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief The number of parameters in an expanded parameter pack.
12336964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned NumExpandedParams;
12346964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
1235127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
123661c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                           unsigned D, unsigned P, bool ParameterPack,
1237127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
1238127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1239d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      TemplateParmPosition(D, P), DefaultArgument(),
12406964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith      DefaultArgumentWasInherited(false), ParameterPack(ParameterPack),
12416964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith      ExpandedParameterPack(false), NumExpandedParams(0)
1242127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
12437e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
12446964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
12456964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           unsigned D, unsigned P,
12466964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           IdentifierInfo *Id, TemplateParameterList *Params,
12476964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           unsigned NumExpansions,
12486964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           TemplateParameterList * const *Expansions);
12496964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
1250127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
12514ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
1252127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
125361c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                                          unsigned P, bool ParameterPack,
125461c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                                          IdentifierInfo *Id,
1255127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
12566964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
12576964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          SourceLocation L, unsigned D,
12586964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          unsigned P,
12596964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          IdentifierInfo *Id,
12606964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          TemplateParameterList *Params,
1261cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko                                 ArrayRef<TemplateParameterList *> Expansions);
12627e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
12636964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
12641e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                      unsigned ID);
12656964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
12666964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                                      unsigned ID,
12676964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                                      unsigned NumExpansions);
12681e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1269127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1270127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1271127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
12721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1273d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \brief Whether this template template parameter is a template
1274d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// parameter pack.
1275d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  ///
1276d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \code
1277d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// template<template <class T> ...MetaFunctions> struct Apply;
1278d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \endcode
127961c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  bool isParameterPack() const { return ParameterPack; }
1280d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
12816964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this parameter pack is a pack expansion.
12826964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12836964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// A template template parameter pack is a pack expansion if its template
12846964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// parameter list contains an unexpanded parameter pack.
12856964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool isPackExpansion() const {
12866964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return ParameterPack &&
12876964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith           getTemplateParameters()->containsUnexpandedParameterPack();
12886964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
12896964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
12906964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this parameter is a template template parameter pack that
12916964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// has a known list of different template parameter lists at different
12926964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// positions.
12936964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12946964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// A parameter pack is an expanded parameter pack when the original parameter
12956964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack's template parameter list was itself a pack expansion, and that
12966964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// expansion has already been expanded. For exampe, given:
12976964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12986964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \code
12996964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// template<typename...Types> struct Outer {
13006964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///   template<template<Types> class...Templates> struct Inner;
13016964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// };
13026964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \endcode
13036964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
13046964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// The parameter pack \c Templates is a pack expansion, which expands the
13056964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack \c Types. When \c Types is supplied with template arguments by
13066964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// instantiating \c Outer, the instantiation of \c Templates is an expanded
13076964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// parameter pack.
13086964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
13096964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
13106964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Retrieves the number of expansion template parameters in
13116964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// an expanded parameter pack.
13126964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned getNumExpansionTemplateParameters() const {
13136964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    assert(ExpandedParameterPack && "Not an expansion parameter pack");
13146964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return NumExpandedParams;
13156964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
13166964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
13176964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Retrieve a particular expansion type within an expanded parameter
13186964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack.
13196964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
13206964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    assert(I < NumExpandedParams && "Out-of-range expansion type index");
13216964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I];
13226964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
13236964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
1324127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1325127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1326d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
1327d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return !DefaultArgument.getArgument().isNull();
1328788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
13297e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1330127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1331d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  const TemplateArgumentLoc &getDefaultArgument() const {
1332d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgument;
1333d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1334d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1335d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Retrieve the location of the default argument, if any.
1336d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  SourceLocation getDefaultArgumentLoc() const;
1337d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1338d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1339d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1340d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1341d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentWasInherited;
1342788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
13437e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1344d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1345d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1346d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1347d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
1348127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
1349d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = Inherited;
1350d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1351d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1352d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1353d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
1354d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgument = TemplateArgumentLoc();
1355d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = false;
1356127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
13577e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY {
1359fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    SourceLocation End = getLocation();
1360fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (hasDefaultArgument() && !defaultArgumentWasInherited())
1361fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      End = getDefaultArgument().getSourceRange().getEnd();
1362fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1363fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  }
1364fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1365127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
136680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
136780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1368bfcc92c3476ada55ceeea49e43e6d2e083252830Argyrios Kyrtzidis
1369d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
13703397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
13717e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
13727e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
13733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
13743e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
13753e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
13763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
13773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
13783e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
13793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
13803e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
13813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
13821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
13831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// template<>
13843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
13853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
13861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplateSpecializationDecl
13873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
13881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Structure that stores information about a class template
139037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
139137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
139237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
139337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
139437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
139537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
13961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
139737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
139837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
1399d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    const TemplateArgumentList *TemplateArgs;
140037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
14011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
140337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
140437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
14053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1406c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
1407c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  struct ExplicitSpecializationInfo {
1408c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The type-as-written.
1409c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    TypeSourceInfo *TypeAsWritten;
1410c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the extern keyword.
1411c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation ExternLoc;
1412c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the template keyword.
1413c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation TemplateKeywordLoc;
1414c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1415c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitSpecializationInfo()
14166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
1417c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  };
1418c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1419c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
14203cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// Does not apply to implicit specializations.
1421c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  ExplicitSpecializationInfo *ExplicitInfo;
14223cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
14237e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
1424d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  const TemplateArgumentList *TemplateArgs;
1425cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
14269cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief The point where this template was instantiated (if any)
14279cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation PointOfInstantiation;
14289cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
1429cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
1430cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
1431d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  unsigned SpecializationKind : 3;
1432cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1433c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
143413c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
1435ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                  DeclContext *DC, SourceLocation StartLoc,
1436ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                  SourceLocation IdLoc,
14373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
1438910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                  const TemplateArgument *Args,
1439910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                  unsigned NumArgs,
14408e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
14411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
144394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
14443e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
14453e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
1446ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1447ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara         SourceLocation StartLoc, SourceLocation IdLoc,
14483e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
1449910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         const TemplateArgument *Args,
1450910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         unsigned NumArgs,
1451cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
1452b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  static ClassTemplateSpecializationDecl *
14531e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  CreateDeserialized(ASTContext &C, unsigned ID);
145494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                            bool Qualified) const override;
1457da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor
1458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
1459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // different "most recent" declaration from this function for the same
1460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // declaration, because we don't override getMostRecentDeclImpl(). But
1461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // it's not clear that we should override that, because the most recent
1462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // declaration as a CXXRecordDecl sometimes is the injected-class-name.
1463ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  ClassTemplateSpecializationDecl *getMostRecentDecl() {
14642dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman    CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
14652dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman                              this)->getMostRecentDecl();
1466b60fae50d38a0291e1c5731b2fb22849d26ca342Richard Smith    while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
1467cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis      // FIXME: Does injected class name need to be in the redeclarations chain?
1468ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
1469ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      Recent = Recent->getPreviousDecl();
1470cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    }
1471cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplateSpecializationDecl>(Recent);
1472cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1473cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
14743e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
147537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
14763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
14771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the template arguments of the class template
147837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
14791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgumentList &getTemplateArgs() const {
1480910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return *TemplateArgs;
14813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
14823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1483cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
1484cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
1485cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
1486cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
1487cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1488cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
14896ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  bool isExplicitSpecialization() const {
14906ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall    return getSpecializationKind() == TSK_ExplicitSpecialization;
14916ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  }
14926ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall
14935a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// \brief True if this declaration is an explicit specialization,
14945a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// explicit instantiation declaration, or explicit instantiation
14955a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// definition.
14965a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  bool isExplicitInstantiationOrSpecialization() const {
14975a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    switch (getTemplateSpecializationKind()) {
14985a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitSpecialization:
14995a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDeclaration:
15005a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDefinition:
15015a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return true;
15025a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
15035a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_Undeclared:
15045a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ImplicitInstantiation:
15055a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return false;
15065a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    }
15075a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    llvm_unreachable("bad template specialization kind");
15085a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
15095a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
1510cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
1511cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
1512cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1513cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
15149cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief Get the point of instantiation (if any), or null if none.
15159cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation getPointOfInstantiation() const {
15169cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    return PointOfInstantiation;
15179cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
15189cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
15199cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  void setPointOfInstantiation(SourceLocation Loc) {
15209cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    assert(Loc.isValid() && "point of instantiation must be valid!");
15219cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    PointOfInstantiation = Loc;
15229cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
15239cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
152437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
152537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
152637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
152737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
15281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::PointerUnion<ClassTemplateDecl *,
152937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
153037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
1531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!isTemplateInstantiation(getSpecializationKind()))
1532e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor      return llvm::PointerUnion<ClassTemplateDecl *,
1533e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor                                ClassTemplatePartialSpecializationDecl *>();
15341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1535651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return getSpecializedTemplateOrPartial();
153637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
15371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
153894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Retrieve the class template or class template partial
153994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// specialization which was specialized by this.
154094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  llvm::PointerUnion<ClassTemplateDecl *,
154194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis                     ClassTemplatePartialSpecializationDecl *>
154294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  getSpecializedTemplateOrPartial() const {
154394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    if (SpecializedPartialSpecialization *PartialSpec
154494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
154594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      return PartialSpec->PartialSpecialization;
154694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1547f8c12146fa2153a6d97b7c92d27d2ece0cd26e79Dmitri Gribenko    return SpecializedTemplate.get<ClassTemplateDecl*>();
154894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
154994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
155037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
155137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
155237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
155337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
155437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
155537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
155637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
155737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
155837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
155937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
156037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
156137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
15621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
156337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
156437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
15651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
156637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
156737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
15681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
156937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
157037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
157137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
157237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
1573d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith                          const TemplateArgumentList *TemplateArgs) {
157494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
157594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Already set to a class template partial specialization!");
15761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SpecializedPartialSpecialization *PS
157737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
157837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
157937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
158037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
158137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
15821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
158394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Note that this class template specialization is an instantiation
158494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// of the given class template.
158594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
158694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
158794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Previously set to a class template partial specialization!");
158894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    SpecializedTemplate = TemplDecl;
158994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
159094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1591fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
1592fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
15933cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  void setTypeAsWritten(TypeSourceInfo *T) {
1594db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1595db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1596c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TypeAsWritten = T;
15973cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  }
15983cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Gets the type of this specialization as it was written by
15993cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// the user, if it was so written.
16003cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  TypeSourceInfo *getTypeAsWritten() const {
16016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
1602c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1603c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1604c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the extern keyword, if present.
1605c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getExternLoc() const {
1606c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
1607c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1608c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the extern keyword.
1609c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setExternLoc(SourceLocation Loc) {
1610db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1611db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1612c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->ExternLoc = Loc;
1613c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1614c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1615c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the template keyword.
1616c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setTemplateKeywordLoc(SourceLocation Loc) {
1617db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1618db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1619c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TemplateKeywordLoc = Loc;
1620c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1621c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the template keyword, if present.
1622c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getTemplateKeywordLoc() const {
1623c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
1624fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
1625fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
1626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SourceRange getSourceRange() const override LLVM_READONLY;
16274a85a73466bfb541cd9c7b57a99292a0b6900b9bAbramo Bagnara
1628c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1629ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Profile(ID, TemplateArgs->asArray(), getASTContext());
1630c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1631c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
16321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
1633ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1634ef8225444452a1486bd721f3285301fe84643b00Stephen Hines          ASTContext &Context) {
1635ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ID.AddInteger(TemplateArgs.size());
1636ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
1637828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
16383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
16393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
164080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
164180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
16429a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstClassTemplateSpecialization &&
16439a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt           K <= lastClassTemplateSpecialization;
16443e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
16453e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1646586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclReader;
1647586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclWriter;
1648c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1649c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
16501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplatePartialSpecializationDecl
16511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public ClassTemplateSpecializationDecl {
1652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
165399ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
16541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The list of template parameters
1655c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1656c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1657833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief The source info for the template arguments as written.
16583cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// FIXME: redundant with TypeAsWritten?
1659c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *ArgsAsWritten;
1660833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1661ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The class template partial specialization from which this
1662ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// class template partial specialization was instantiated.
1663ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1664ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The boolean value will be true to indicate that this class template
1665ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// partial specialization was specialized at this level.
1666ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
1667ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      InstantiatedFromMember;
1668ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
166913c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1670ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         DeclContext *DC,
1671ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         SourceLocation StartLoc,
1672ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         SourceLocation IdLoc,
1673c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1674c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
1675910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                         const TemplateArgument *Args,
1676910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                         unsigned NumArgs,
1677c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella                               const ASTTemplateArgumentListInfo *ArgsAsWritten,
167837fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith                               ClassTemplatePartialSpecializationDecl *PrevDecl);
1679ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
16806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ClassTemplatePartialSpecializationDecl(ASTContext &C)
16816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
16826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      TemplateParams(nullptr), ArgsAsWritten(nullptr),
16836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      InstantiatedFromMember(nullptr, false) {}
1684c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1685c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1686c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
1687ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1688ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara         SourceLocation StartLoc, SourceLocation IdLoc,
1689c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1690c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
1691910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         const TemplateArgument *Args,
1692910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         unsigned NumArgs,
1693d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall         const TemplateArgumentListInfo &ArgInfos,
16943cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall         QualType CanonInjectedType,
169537fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith         ClassTemplatePartialSpecializationDecl *PrevDecl);
1696c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
169794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  static ClassTemplatePartialSpecializationDecl *
16981e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  CreateDeserialized(ASTContext &C, unsigned ID);
169994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1700ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
1701cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplatePartialSpecializationDecl>(
17022dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<ClassTemplateSpecializationDecl *>(
17032dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman               this)->getMostRecentDecl());
1704cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1705cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1706c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1707c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1708c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1709c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1710c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1711833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the template arguments as written.
1712c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
1713833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return ArgsAsWritten;
1714833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1715833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1716ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the member class template partial specialization from
1717ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// which this particular class template partial specialization was
1718ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// instantiated.
1719ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1720ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1721ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1722ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct Outer {
1723ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1724ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*> { }; // #1
1725ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1726ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1727ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// Outer<float>::Inner<int*> ii;
1728ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1729ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1730ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
1731ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// end up instantiating the partial specialization
1732ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
1733ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// template partial specialization \c Outer<T>::Inner<U*>. Given
1734ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, this function would return
1735ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<T>::Inner<U*>.
1736ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
1737bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    ClassTemplatePartialSpecializationDecl *First =
1738bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1739ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getPointer();
1740ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1741ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1742ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setInstantiatedFromMember(
1743ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
1744bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    ClassTemplatePartialSpecializationDecl *First =
1745bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1746ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    First->InstantiatedFromMember.setPointer(PartialSpec);
1747ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1748ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1749ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Determines whether this class template partial specialization
1750ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template was a specialization of a member partial specialization.
1751ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1752ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In the following example, the member template partial specialization
1753ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c X<int>::Inner<T*> is a member specialization.
1754ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1755ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1756ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1757ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X {
1758ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1759ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*>;
1760ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1761ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1762ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<> template<typename T>
1763ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X<int>::Inner<T*> { /* ... */ };
1764ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1765ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  bool isMemberSpecialization() {
1766bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    ClassTemplatePartialSpecializationDecl *First =
1767bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1768ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getInt();
1769ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1770ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1771ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Note that this member template is a specialization.
1772ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setMemberSpecialization() {
1773bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola    ClassTemplatePartialSpecializationDecl *First =
1774bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1775ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    assert(First->InstantiatedFromMember.getPointer() &&
1776ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor           "Only member templates can be member template specializations");
1777ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.setInt(true);
1778ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
177931f17ecbef57b5679c017c375db330546b7b5145John McCall
178031f17ecbef57b5679c017c375db330546b7b5145John McCall  /// Retrieves the injected specialization type for this partial
178131f17ecbef57b5679c017c375db330546b7b5145John McCall  /// specialization.  This is not the same as the type-decl-type for
178231f17ecbef57b5679c017c375db330546b7b5145John McCall  /// this partial specialization, which is an InjectedClassNameType.
178331f17ecbef57b5679c017c375db330546b7b5145John McCall  QualType getInjectedSpecializationType() const {
178431f17ecbef57b5679c017c375db330546b7b5145John McCall    assert(getTypeForDecl() && "partial specialization has no type set!");
178531f17ecbef57b5679c017c375db330546b7b5145John McCall    return cast<InjectedClassNameType>(getTypeForDecl())
178631f17ecbef57b5679c017c375db330546b7b5145John McCall             ->getInjectedSpecializationType();
178731f17ecbef57b5679c017c375db330546b7b5145John McCall  }
1788ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1789c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1790c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
179180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
179280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
179380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall    return K == ClassTemplatePartialSpecialization;
1794c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1795c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
17968fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclReader;
17978fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclWriter;
17983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
17993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
18003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
18017c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass ClassTemplateDecl : public RedeclarableTemplateDecl {
18020054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  static void DeallocateCommon(void *Ptr);
1803ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
18043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
18055953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
18065953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
18079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
1808c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    Common() : LazySpecializations() { }
1809ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
18105953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
18115953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
1812d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
18137da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1814c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1815c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
1816d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
1817c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1818c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
18197da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
18207da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1821ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1822c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// \brief If non-null, points to an array of specializations (including
18236982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// partial specializations) known only by their external declaration IDs.
1824c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    ///
1825c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// The first value in the array is the number of of specializations/
1826c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// partial specializations that follow.
1827c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    uint32_t *LazySpecializations;
18285953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
18295953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1830c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  /// \brief Load any lazily-loaded specializations from the external source.
1831e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  void LoadLazySpecializations() const;
1832ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1833cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of specializations of this class template.
1834e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
1835e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  getSpecializations() const;
1836cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1837cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of partial specializations of this class
1838cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// template.
1839d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
1840c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  getPartialSpecializations();
1841cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
18426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
18436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                    DeclarationName Name, TemplateParameterList *Params,
18446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                    NamedDecl *Decl)
18456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
18469a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
1847651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CommonBase *newCommon(ASTContext &C) const override;
18489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1849e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  Common *getCommonPtr() const {
18509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
18519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18523e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
18533e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
1854d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Get the underlying class declarations of the template.
18553e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
18563e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
18573e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
18583e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1859d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Returns whether this template declaration defines the primary
186013fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// class pattern.
186113fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
186213fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
186313fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
186413fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
1865d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Create a class template node.
18663e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
18673e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
18683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
18693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
18705953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
18715953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
18723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1873d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Create an empty class template node.
18741e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
18759a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
1876cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the specialization with the provided arguments if it exists,
1877cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// otherwise return the insertion point.
1878cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplateSpecializationDecl *
1879ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
1880cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1881cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified specialization knowing that it is not already
1882cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// in. InsertPos must be obtained from findSpecialization.
1883bef1a7b9c175d37e4a727e6ce68bd05232fa6970Argyrios Kyrtzidis  void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
18843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1885651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ClassTemplateDecl *getCanonicalDecl() override {
18867c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<ClassTemplateDecl>(
18877c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
18889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18899eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const ClassTemplateDecl *getCanonicalDecl() const {
18907c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<ClassTemplateDecl>(
18917c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
18929eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18939eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18949eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
18959eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
1896ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  ClassTemplateDecl *getPreviousDecl() {
18977c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<ClassTemplateDecl>(
18982dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
18999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
19009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
19019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
19029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
1903ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  const ClassTemplateDecl *getPreviousDecl() const {
19047c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<ClassTemplateDecl>(
19052dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<const RedeclarableTemplateDecl *>(
19062dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman               this)->getPreviousDecl());
19079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
19089eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1909daaabf72e77757d62bc9584927dee22968669514Rafael Espindola  ClassTemplateDecl *getMostRecentDecl() {
1910daaabf72e77757d62bc9584927dee22968669514Rafael Espindola    return cast<ClassTemplateDecl>(
19112dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman        static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
1912daaabf72e77757d62bc9584927dee22968669514Rafael Espindola  }
1913daaabf72e77757d62bc9584927dee22968669514Rafael Espindola  const ClassTemplateDecl *getMostRecentDecl() const {
1914daaabf72e77757d62bc9584927dee22968669514Rafael Espindola    return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
1915daaabf72e77757d62bc9584927dee22968669514Rafael Espindola  }
1916daaabf72e77757d62bc9584927dee22968669514Rafael Espindola
19179eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
19187c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<ClassTemplateDecl>(
19197c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
19209eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
19219eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1922cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the partial specialization with the provided arguments if it
1923cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// exists, otherwise return the insertion point.
1924cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1925ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
1926cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1927cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified partial specialization knowing that it is not
1928cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// already in. InsertPos must be obtained from findPartialSpecialization.
1929cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
1930bef1a7b9c175d37e4a727e6ce68bd05232fa6970Argyrios Kyrtzidis                                void *InsertPos);
1931cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1932dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Retrieve the partial specializations as an ordered list.
1933dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  void getPartialSpecializations(
1934686775deca8b8685eb90801495880e3abdd844c2Chris Lattner          SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
1935ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1936b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1937b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1938b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1939cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param T a dependent type that names a specialization of this class
1940b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1941b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1942b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1943b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1944b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
1945ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1946cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Find a class template partial specialization which was instantiated
1947cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization.
1948cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1949cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param D a member class template partial specialization.
1950cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1951cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \returns the class template partial specialization which was instantiated
1952cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization, or NULL if no such partial
1953cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// specialization exists.
1954cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1955cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findPartialSpecInstantiatedFromMember(
1956cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                                     ClassTemplatePartialSpecializationDecl *D);
19571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19583cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Retrieve the template specialization type of the
19593cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// injected-class-name for this class template.
19607da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
19617da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
19627da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
19637da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
19647da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
19657da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
19667da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
19677da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
19687da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
19697da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
19707da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
19717da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
197224bae92f08ae098cc50a602d8cf1273b423e14daDouglas Gregor  QualType getInjectedClassNameSpecialization();
19737da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
19749f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
1975651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<spec_iterator> spec_range;
1976651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
1977651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  spec_range specializations() const {
1978651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return spec_range(spec_begin(), spec_end());
1979651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
19809f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
1981e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_begin() const {
19829f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
19839f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19849f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
1985e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_end() const {
19869f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
19879f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19889f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
199080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
199180cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ClassTemplate; }
19925953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1993d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
19943397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
19953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
19963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1997d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of a friend template.
1998dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///
1999d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// For example:
2000d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
2001d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// template \<typename T> class A {
2002dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   friend class MyVector<T>; // not a friend template
2003d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<typename U> friend class B; // not a friend template
2004d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<typename U> friend class Foo<T>::Nested; // friend template
2005c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// };
2006d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
2007d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
2008d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \note This class is not currently in use.  All of the above
2009c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// will yield a FriendDecl, not a FriendTemplateDecl.
2010dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallclass FriendTemplateDecl : public Decl {
201199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
2012dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
201332f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
2014dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2015dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallprivate:
2016dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The number of template parameters;  always non-zero.
2017dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned NumParams;
2018dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2019dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The parameter list.
2020dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList **Params;
2021dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2022dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The declaration that's a friend of this class.
2023dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendUnion Friend;
2024dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2025dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Location of the 'friend' specifier.
2026dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation FriendLoc;
2027dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2028dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2029dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
2030ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                     unsigned NParams,
2031dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     TemplateParameterList **Params,
2032dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     FriendUnion Friend,
2033dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     SourceLocation FriendLoc)
2034dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    : Decl(Decl::FriendTemplate, DC, Loc),
2035dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      NumParams(NParams),
2036dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Params(Params),
2037dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Friend(Friend),
2038dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      FriendLoc(FriendLoc)
2039dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  {}
2040dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2041554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  FriendTemplateDecl(EmptyShell Empty)
2042554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis    : Decl(Decl::FriendTemplate, Empty),
2043554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis      NumParams(0),
20446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      Params(nullptr)
2045554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  {}
2046554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2047dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
2048dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static FriendTemplateDecl *Create(ASTContext &Context,
2049dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    DeclContext *DC, SourceLocation Loc,
2050ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                                    unsigned NParams,
2051dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    TemplateParameterList **Params,
2052dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    FriendUnion Friend,
2053dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    SourceLocation FriendLoc);
2054dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
20551e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2056554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2057dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated type (or
2058dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a dependent member type of a templated type), return that
2059dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// type;  otherwise return null.
206032f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  TypeSourceInfo *getFriendType() const {
206132f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return Friend.dyn_cast<TypeSourceInfo*>();
2062dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2063dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2064dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated function (or
2065dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a member function of a templated type), return that type;
2066dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// otherwise return null.
2067dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  NamedDecl *getFriendDecl() const {
2068dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Friend.dyn_cast<NamedDecl*>();
2069dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2070dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2071d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Retrieves the location of the 'friend' keyword.
2072dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation getFriendLoc() const {
2073dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return FriendLoc;
2074dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2075dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2076dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList *getTemplateParameterList(unsigned i) const {
2077dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    assert(i <= NumParams);
2078dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Params[i];
2079dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2080dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2081dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned getNumTemplateParameters() const {
2082dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return NumParams;
2083dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2084dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2085dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Implement isa/cast/dyncast/etc.
208680cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
208780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2088554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2089d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
2090dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall};
2091dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2092d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of an alias template.
20933e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith///
2094d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// For example:
2095d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
2096d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
2097d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
20987c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
20993e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static void DeallocateCommon(void *Ptr);
21003e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21013e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithprotected:
21023e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  typedef CommonBase Common;
21033e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
21056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                        DeclarationName Name, TemplateParameterList *Params,
21066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                        NamedDecl *Decl)
21076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
21086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                 Decl) {}
21093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CommonBase *newCommon(ASTContext &C) const override;
21113e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  Common *getCommonPtr() {
21133e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
21143e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21153e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21163e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithpublic:
21173e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// Get the underlying function declaration of the template.
21183e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasDecl *getTemplatedDecl() const {
21193e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return static_cast<TypeAliasDecl*>(TemplatedDecl);
21203e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21213e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21223e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  TypeAliasTemplateDecl *getCanonicalDecl() override {
21247c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<TypeAliasTemplateDecl>(
21257c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
21263e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21273e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  const TypeAliasTemplateDecl *getCanonicalDecl() const {
21287c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<TypeAliasTemplateDecl>(
21297c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
21303e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21313e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21323e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Retrieve the previous declaration of this function template, or
21333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// NULL if no such declaration exists.
2134ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  TypeAliasTemplateDecl *getPreviousDecl() {
21357c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<TypeAliasTemplateDecl>(
21362dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
21373e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21383e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21393e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Retrieve the previous declaration of this function template, or
21403e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// NULL if no such declaration exists.
2141ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  const TypeAliasTemplateDecl *getPreviousDecl() const {
21427c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<TypeAliasTemplateDecl>(
21432dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<const RedeclarableTemplateDecl *>(
21442dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman               this)->getPreviousDecl());
21453e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21463e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21473e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
21487c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<TypeAliasTemplateDecl>(
21497c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
21503e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21513e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2152ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
21533e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Create a function template node.
21543e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
21553e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       SourceLocation L,
21563e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       DeclarationName Name,
21573e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       TemplateParameterList *Params,
21583e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       NamedDecl *Decl);
21593e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21603e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Create an empty alias template node.
21611e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
21623e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21633e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  // Implement isa/cast/dyncast support
21643e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
21653e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
21663e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21673e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  friend class ASTDeclReader;
21683e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  friend class ASTDeclWriter;
21693e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith};
21703e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2171d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of a function specialization at template class scope.
2172d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
2173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// This is a non-standard extension needed to support MSVC.
2174d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
2175af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// For example:
2176d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
2177af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// template <class T>
2178af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// class A {
2179af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet///    template <class U> void foo(U a) { }
2180af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet///    template<> void foo(int a) { }
2181af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// }
2182d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
2183af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet///
2184af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// "template<> foo(int a)" will be saved in Specialization as a normal
2185af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// CXXMethodDecl. Then during an instantiation of class A, it will be
2186af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// transformed into an actual function specialization.
2187af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichetclass ClassScopeFunctionSpecializationDecl : public Decl {
218899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
218999ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
2190af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
21916b02009359a462ffe633696a4441313b462e6566Nico Weber                                       CXXMethodDecl *FD, bool Args,
21926b02009359a462ffe633696a4441313b462e6566Nico Weber                                       TemplateArgumentListInfo TemplArgs)
2193af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
21946b02009359a462ffe633696a4441313b462e6566Nico Weber      Specialization(FD), HasExplicitTemplateArgs(Args),
21956b02009359a462ffe633696a4441313b462e6566Nico Weber      TemplateArgs(TemplArgs) {}
2196af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2197af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
2198af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
2199af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2200af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  CXXMethodDecl *Specialization;
22016b02009359a462ffe633696a4441313b462e6566Nico Weber  bool HasExplicitTemplateArgs;
22026b02009359a462ffe633696a4441313b462e6566Nico Weber  TemplateArgumentListInfo TemplateArgs;
2203af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2204af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichetpublic:
2205af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  CXXMethodDecl *getSpecialization() const { return Specialization; }
22066b02009359a462ffe633696a4441313b462e6566Nico Weber  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
22076b02009359a462ffe633696a4441313b462e6566Nico Weber  const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
2208af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2209af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
2210af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet                                                      DeclContext *DC,
2211af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet                                                      SourceLocation Loc,
22126b02009359a462ffe633696a4441313b462e6566Nico Weber                                                      CXXMethodDecl *FD,
22136b02009359a462ffe633696a4441313b462e6566Nico Weber                                                   bool HasExplicitTemplateArgs,
22146b02009359a462ffe633696a4441313b462e6566Nico Weber                                        TemplateArgumentListInfo TemplateArgs) {
2215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return new (C, DC) ClassScopeFunctionSpecializationDecl(
2216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
2217af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  }
2218af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
22191e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ClassScopeFunctionSpecializationDecl *
22201e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  CreateDeserialized(ASTContext &Context, unsigned ID);
22211e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
2222af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  // Implement isa/cast/dyncast/etc.
2223af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2224af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  static bool classofKind(Kind K) {
2225af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    return K == Decl::ClassScopeFunctionSpecialization;
2226af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  }
2227af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2228af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  friend class ASTDeclReader;
2229af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  friend class ASTDeclWriter;
2230af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet};
2231af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2232e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
22331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
2234e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
2235e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
2236ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// \brief Represents a variable template specialization, which refers to
2237ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// a variable template with a given set of template arguments.
2238ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo///
2239ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// Variable template specializations represent both explicit
2240ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// specializations of variable templates, as in the example below, and
2241ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// implicit instantiations of variable templates.
2242ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo///
2243ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// \code
2244ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2245ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo///
2246ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// template<>
2247ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// constexpr float pi<float>; // variable template specialization pi<float>
2248ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// \endcode
2249ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplateSpecializationDecl : public VarDecl,
2250ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                      public llvm::FoldingSetNode {
2251ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2252ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Structure that stores information about a variable template
2253ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization that was instantiated from a variable template partial
2254ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization.
2255ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  struct SpecializedPartialSpecialization {
2256ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The variable template partial specialization from which this
2257ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// variable template specialization was instantiated.
2258ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *PartialSpecialization;
2259ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2260ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The template argument list deduced for the variable template
2261ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// partial specialization itself.
2262d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    const TemplateArgumentList *TemplateArgs;
2263ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
2264ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2265ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The template that this specialization specializes.
2266ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2267ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SpecializedTemplate;
2268ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2269ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Further info for explicit template specialization/instantiation.
2270ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  struct ExplicitSpecializationInfo {
2271ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The type-as-written.
2272ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    TypeSourceInfo *TypeAsWritten;
2273ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The location of the extern keyword.
2274ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SourceLocation ExternLoc;
2275ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The location of the template keyword.
2276ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SourceLocation TemplateKeywordLoc;
2277ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2278ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitSpecializationInfo()
22796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
2280ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
2281ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2282ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Further info for explicit template specialization/instantiation.
2283ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Does not apply to implicit specializations.
2284ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ExplicitSpecializationInfo *ExplicitInfo;
2285ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2286ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The template arguments used to describe this specialization.
2287d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  const TemplateArgumentList *TemplateArgs;
2288ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateArgumentListInfo TemplateArgsInfo;
2289ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2290ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The point where this template was instantiated (if any).
2291ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation PointOfInstantiation;
2292ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2293ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The kind of specialization this declaration refers to.
2294ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Really a value of type TemplateSpecializationKind.
2295ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  unsigned SpecializationKind : 3;
2296ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2297ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoprotected:
22986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
2299ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                SourceLocation StartLoc, SourceLocation IdLoc,
2300ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                VarTemplateDecl *SpecializedTemplate,
2301ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                QualType T, TypeSourceInfo *TInfo,
2302ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                StorageClass S, const TemplateArgument *Args,
2303ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                unsigned NumArgs);
2304ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
23056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2306ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2307ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufopublic:
2308ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateSpecializationDecl *
2309ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2310ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2311ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
2312ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         unsigned NumArgs);
2313ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
2314ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                                           unsigned ID);
2315ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                            bool Qualified) const override;
2318ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2319ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateSpecializationDecl *getMostRecentDecl() {
23202dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman    VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2321ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplateSpecializationDecl>(Recent);
2322ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2323ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2324ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the template that this specialization specializes.
2325ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getSpecializedTemplate() const;
2326ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2327ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the template arguments of the variable template
2328ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization.
2329ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2330ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2331ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  // TODO: Always set this when creating the new specialization?
2332ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
2333ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2334ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const TemplateArgumentListInfo &getTemplateArgsInfo() const {
2335ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return TemplateArgsInfo;
2336ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2337ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2338ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Determine the kind of specialization that this
2339ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// declaration represents.
2340ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateSpecializationKind getSpecializationKind() const {
2341ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return static_cast<TemplateSpecializationKind>(SpecializationKind);
2342ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2343ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2344ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isExplicitSpecialization() const {
2345ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return getSpecializationKind() == TSK_ExplicitSpecialization;
2346ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2347ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2348ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief True if this declaration is an explicit specialization,
2349ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// explicit instantiation declaration, or explicit instantiation
2350ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// definition.
2351ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isExplicitInstantiationOrSpecialization() const {
2352ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    switch (getTemplateSpecializationKind()) {
2353ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ExplicitSpecialization:
2354ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ExplicitInstantiationDeclaration:
2355ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ExplicitInstantiationDefinition:
2356ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return true;
2357ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2358ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_Undeclared:
2359ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ImplicitInstantiation:
2360ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return false;
2361ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    }
2362ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    llvm_unreachable("bad template specialization kind");
2363ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2364ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2365ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setSpecializationKind(TemplateSpecializationKind TSK) {
2366ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializationKind = TSK;
2367ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2368ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2369ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Get the point of instantiation (if any), or null if none.
2370ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation getPointOfInstantiation() const {
2371ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return PointOfInstantiation;
2372ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2373ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2374ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setPointOfInstantiation(SourceLocation Loc) {
2375ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(Loc.isValid() && "point of instantiation must be valid!");
2376ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PointOfInstantiation = Loc;
2377ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2378ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2379ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief If this variable template specialization is an instantiation of
2380ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// a template (rather than an explicit specialization), return the
2381ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template or variable template partial specialization from which
2382ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// it was instantiated.
2383ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2384ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getInstantiatedFrom() const {
2385ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
2386ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
2387ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
2388ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return llvm::PointerUnion<VarTemplateDecl *,
2389ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                VarTemplatePartialSpecializationDecl *>();
2390ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2391ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (SpecializedPartialSpecialization *PartialSpec =
2392ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2393ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return PartialSpec->PartialSpecialization;
2394ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2395ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return SpecializedTemplate.get<VarTemplateDecl *>();
2396ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2397ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2398ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the variable template or variable template partial
2399ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization which was specialized by this.
2400ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2401ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getSpecializedTemplateOrPartial() const {
2402ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (SpecializedPartialSpecialization *PartialSpec =
2403ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2404ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return PartialSpec->PartialSpecialization;
2405ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2406ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return SpecializedTemplate.get<VarTemplateDecl *>();
2407ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2408ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2409ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the set of template arguments that should be used
2410ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// to instantiate the initializer of the variable template or variable
2411ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template partial specialization from which this variable template
2412ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization was instantiated.
2413ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2414ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \returns For a variable template specialization instantiated from the
2415ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// primary template, this function will return the same template arguments
2416ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// as getTemplateArgs(). For a variable template specialization instantiated
2417ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// from a variable template partial specialization, this function will the
2418ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// return deduced template arguments for the variable template partial
2419ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization itself.
2420ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const TemplateArgumentList &getTemplateInstantiationArgs() const {
2421ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (SpecializedPartialSpecialization *PartialSpec =
2422ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2423ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return *PartialSpec->TemplateArgs;
2424ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2425ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return getTemplateArgs();
2426ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2427ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2428ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Note that this variable template specialization is actually an
2429ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiation of the given variable template partial specialization whose
2430ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template arguments have been deduced.
2431ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
2432d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith                          const TemplateArgumentList *TemplateArgs) {
2433ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2434ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           "Already set to a variable template partial specialization!");
2435ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializedPartialSpecialization *PS =
2436ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        new (getASTContext()) SpecializedPartialSpecialization();
2437ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PS->PartialSpecialization = PartialSpec;
2438ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PS->TemplateArgs = TemplateArgs;
2439ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializedTemplate = PS;
2440ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2441ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2442ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Note that this variable template specialization is an instantiation
2443ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// of the given variable template.
2444ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setInstantiationOf(VarTemplateDecl *TemplDecl) {
2445ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2446ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           "Previously set to a variable template partial specialization!");
2447ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializedTemplate = TemplDecl;
2448ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2449ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2450ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Sets the type of this specialization as it was written by
2451ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// the user.
2452ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setTypeAsWritten(TypeSourceInfo *T) {
2453ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (!ExplicitInfo)
2454ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2455ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitInfo->TypeAsWritten = T;
2456ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2457ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Gets the type of this specialization as it was written by
2458ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// the user, if it was so written.
2459ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TypeSourceInfo *getTypeAsWritten() const {
24606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
2461ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2462ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2463ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Gets the location of the extern keyword, if present.
2464ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation getExternLoc() const {
2465ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2466ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2467ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Sets the location of the extern keyword.
2468ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setExternLoc(SourceLocation Loc) {
2469ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (!ExplicitInfo)
2470ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2471ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitInfo->ExternLoc = Loc;
2472ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2473ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2474ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Sets the location of the template keyword.
2475ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setTemplateKeywordLoc(SourceLocation Loc) {
2476ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (!ExplicitInfo)
2477ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2478ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitInfo->TemplateKeywordLoc = Loc;
2479ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2480ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Gets the location of the template keyword, if present.
2481ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation getTemplateKeywordLoc() const {
2482ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2483ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2484ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2485ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void Profile(llvm::FoldingSetNodeID &ID) const {
2486ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Profile(ID, TemplateArgs->asArray(), getASTContext());
2487ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2488ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2489ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static void Profile(llvm::FoldingSetNodeID &ID,
2490ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                      ArrayRef<TemplateArgument> TemplateArgs,
2491ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                      ASTContext &Context) {
2492ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ID.AddInteger(TemplateArgs.size());
2493ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
2494ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      TemplateArgs[Arg].Profile(ID, Context);
2495ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2496ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2497ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2498ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classofKind(Kind K) {
2499ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return K >= firstVarTemplateSpecialization &&
2500ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           K <= lastVarTemplateSpecialization;
2501ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2502ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2503ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclReader;
2504ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclWriter;
2505ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo};
2506ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2507ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplatePartialSpecializationDecl
2508ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    : public VarTemplateSpecializationDecl {
2509651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void anchor() override;
2510ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2511ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The list of template parameters
2512ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateParameterList *TemplateParams;
2513ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2514ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The source info for the template arguments as written.
2515ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// FIXME: redundant with TypeAsWritten?
2516c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *ArgsAsWritten;
2517ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2518ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The variable template partial specialization from which this
2519ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template partial specialization was instantiated.
2520ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2521ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// The boolean value will be true to indicate that this variable template
2522ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// partial specialization was specialized at this level.
2523ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2524ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  InstantiatedFromMember;
2525ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2526ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl(
2527ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2528ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      SourceLocation IdLoc, TemplateParameterList *Params,
2529ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2530ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
253137fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith      const ASTTemplateArgumentListInfo *ArgInfos);
2532ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
25336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  VarTemplatePartialSpecializationDecl(ASTContext &Context)
25346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
25356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      TemplateParams(nullptr), ArgsAsWritten(nullptr),
25366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      InstantiatedFromMember(nullptr, false) {}
2537ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2538ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufopublic:
2539ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplatePartialSpecializationDecl *
2540ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2541ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         SourceLocation IdLoc, TemplateParameterList *Params,
2542ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         VarTemplateDecl *SpecializedTemplate, QualType T,
2543ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
254437fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith         unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
2545ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2546ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
2547ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                                                  unsigned ID);
2548ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2549ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2550ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplatePartialSpecializationDecl>(
25512dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman             static_cast<VarTemplateSpecializationDecl *>(
25522dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman               this)->getMostRecentDecl());
2553ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2554ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2555ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Get the list of template parameters
2556ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateParameterList *getTemplateParameters() const {
2557ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return TemplateParams;
2558ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2559ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2560ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Get the template arguments as written.
2561c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2562ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ArgsAsWritten;
2563ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2564ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2565ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the member variable template partial specialization from
2566ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// which this particular variable template partial specialization was
2567ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiated.
2568ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2569ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \code
2570ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template<typename T>
2571ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// struct Outer {
2572ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U Inner;
2573ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U* Inner<U*> = (U*)(0); // #1
2574ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// };
2575ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2576ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template int* Outer<float>::Inner<int*>;
2577ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \endcode
2578ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2579ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2580ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// end up instantiating the partial specialization
2581ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2582ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2583ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c Outer<float>::Inner<U*>, this function would return
2584ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c Outer<T>::Inner<U*>.
2585ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
2586ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2587bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2588ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return First->InstantiatedFromMember.getPointer();
2589ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2590ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2591ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void
2592ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2593ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2594bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2595ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    First->InstantiatedFromMember.setPointer(PartialSpec);
2596ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2597ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2598ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Determines whether this variable template partial specialization
2599ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// was a specialization of a member partial specialization.
2600ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2601ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// In the following example, the member template partial specialization
2602ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c X<int>::Inner<T*> is a member specialization.
2603ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2604ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \code
2605ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template<typename T>
2606ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// struct X {
2607ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U Inner;
2608ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U* Inner<U*> = (U*)(0);
2609ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// };
2610ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2611ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template<> template<typename T>
2612ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2613ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \endcode
2614ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isMemberSpecialization() {
2615ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2616bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2617ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return First->InstantiatedFromMember.getInt();
2618ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2619ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2620ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Note that this member template is a specialization.
2621ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setMemberSpecialization() {
2622ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2623bc6509175e1ce5cc1b48d1b97ac8d23d8b74167cRafael Espindola        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2624ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(First->InstantiatedFromMember.getPointer() &&
2625ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           "Only member templates can be member template specializations");
2626ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return First->InstantiatedFromMember.setInt(true);
2627ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2628ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2629ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2630ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classofKind(Kind K) {
2631ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return K == VarTemplatePartialSpecialization;
2632ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2633ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2634ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclReader;
2635ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclWriter;
2636ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo};
2637ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2638ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// Declaration of a variable template.
2639ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplateDecl : public RedeclarableTemplateDecl {
2640ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static void DeallocateCommon(void *Ptr);
2641ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2642ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoprotected:
2643ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Data that is common to all of the declarations of a given
2644ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template.
2645ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  struct Common : CommonBase {
2646ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    Common() : LazySpecializations() {}
2647ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2648ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The variable template specializations for this variable
2649ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// template, including explicit specializations and instantiations.
2650ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
2651ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2652ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The variable template partial specializations for this variable
2653ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// template.
2654ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
2655ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PartialSpecializations;
2656ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2657ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief If non-null, points to an array of specializations (including
2658ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// partial specializations) known ownly by their external declaration IDs.
2659ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ///
2660ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// The first value in the array is the number of of specializations/
2661ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// partial specializations that follow.
2662ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    uint32_t *LazySpecializations;
2663ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
2664ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2665ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Load any lazily-loaded specializations from the external source.
2666ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void LoadLazySpecializations() const;
2667ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2668ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the set of specializations of this variable template.
2669ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
2670ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getSpecializations() const;
2671ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2672ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the set of partial specializations of this class
2673ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template.
2674ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
2675ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getPartialSpecializations();
2676ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
26776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
26786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                  DeclarationName Name, TemplateParameterList *Params,
26796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                  NamedDecl *Decl)
26806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
2681ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2682651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CommonBase *newCommon(ASTContext &C) const override;
2683ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2684ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  Common *getCommonPtr() const {
2685ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2686ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2687ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2688ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufopublic:
2689ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Get the underlying variable declarations of the template.
2690ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarDecl *getTemplatedDecl() const {
2691ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return static_cast<VarDecl *>(TemplatedDecl);
2692ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2693ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2694ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Returns whether this template declaration defines the primary
2695ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable pattern.
2696ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isThisDeclarationADefinition() const {
2697ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return getTemplatedDecl()->isThisDeclarationADefinition();
2698ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2699ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2700439d665f4d1066ee5ebd8dd0938d85be83d490c4Larisse Voufo  VarTemplateDecl *getDefinition();
2701439d665f4d1066ee5ebd8dd0938d85be83d490c4Larisse Voufo
2702ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Create a variable template node.
2703ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
2704ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                 SourceLocation L, DeclarationName Name,
2705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 TemplateParameterList *Params,
2706651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                 VarDecl *Decl);
2707ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2708ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Create an empty variable template node.
2709ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2710ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2711ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Return the specialization with the provided arguments if it exists,
2712ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// otherwise return the insertion point.
2713ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateSpecializationDecl *
2714ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2715ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2716ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Insert the specified specialization knowing that it is not already
2717ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// in. InsertPos must be obtained from findSpecialization.
2718ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
2719ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2720651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  VarTemplateDecl *getCanonicalDecl() override {
2721ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
2722ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2723ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const VarTemplateDecl *getCanonicalDecl() const {
2724ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
2725ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2726ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2727ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the previous declaration of this variable template, or
2728ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// NULL if no such declaration exists.
2729ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getPreviousDecl() {
2730ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast_or_null<VarTemplateDecl>(
27312dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman        static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
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  const VarTemplateDecl *getPreviousDecl() const {
2737ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast_or_null<VarTemplateDecl>(
27382dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman            static_cast<const RedeclarableTemplateDecl *>(
27392dc57f42574c8b2cda72cae06c0220fd7fab8c0eAaron Ballman              this)->getPreviousDecl());
2740ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2741ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2742ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getInstantiatedFromMemberTemplate() {
2743ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast_or_null<VarTemplateDecl>(
2744ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
2745ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2746ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2747ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Return the partial specialization with the provided arguments if it
2748ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// exists, otherwise return the insertion point.
2749ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *
2750ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2751ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2752ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Insert the specified partial specialization knowing that it is not
2753ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// already in. InsertPos must be obtained from findPartialSpecialization.
2754ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
2755ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                void *InsertPos);
2756ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2757ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the partial specializations as an ordered list.
2758ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void getPartialSpecializations(
2759ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
2760ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2761ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Find a variable template partial specialization which was
2762ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiated
2763ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// from the given member partial specialization.
2764ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2765ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \param D a member variable template partial specialization.
2766ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2767ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \returns the variable template partial specialization which was
2768ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiated
2769ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// from the given member partial specialization, or NULL if no such partial
2770ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization exists.
2771ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
2772ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      VarTemplatePartialSpecializationDecl *D);
2773ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2774ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
2775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef llvm::iterator_range<spec_iterator> spec_range;
2776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2777651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  spec_range specializations() const {
2778651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return spec_range(spec_begin(), spec_end());
2779651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
2780ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2781ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  spec_iterator spec_begin() const {
2782ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getSpecializations(), false);
2783ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2784ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2785ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  spec_iterator spec_end() const {
2786ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getSpecializations(), true);
2787ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2788ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2789ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  // Implement isa/cast/dyncast support
2790ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2791ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classofKind(Kind K) { return K == VarTemplate; }
2792ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2793ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclReader;
2794ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclWriter;
2795ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo};
2796ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2797aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
2798aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
2799aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
2800