DeclTemplate.h revision d0629eb137d06bf6d46a430abdb7fa044909298b
1aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
2aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
3aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//                     The LLVM Compiler Infrastructure
4aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
5aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// This file is distributed under the University of Illinois Open Source
6aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// License. See LICENSE.TXT for details.
7aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
8aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
9d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
10d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \file
11d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Defines the C++ template declaration subclasses.
12d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
13aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
14aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
15aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
16aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#define LLVM_CLANG_AST_DECLTEMPLATE_H
17aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1855f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor#include "clang/AST/DeclCXX.h"
197c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor#include "clang/AST/Redeclarable.h"
20275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall#include "clang/AST/TemplateBase.h"
21f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor#include "llvm/ADT/PointerUnion.h"
22aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar#include "llvm/Support/Compiler.h"
233f3ce82674b44a58a2af7d90feb55acd906dd762Anders Carlsson#include <limits>
2455f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
25aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregornamespace clang {
26aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
27aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList;
28aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateDecl;
299eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneclass RedeclarableTemplateDecl;
30aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl;
31aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass ClassTemplateDecl;
32c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorclass ClassTemplatePartialSpecializationDecl;
33aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTypeParmDecl;
34aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl;
35aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl;
363e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithclass TypeAliasTemplateDecl;
37ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplateDecl;
38ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplatePartialSpecializationDecl;
39aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
40f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor/// \brief Stores a template parameter of any kind.
41f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregortypedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
42f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor                            TemplateTemplateParmDecl*> TemplateParameter;
43f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
44d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Stores a list of template parameters for a TemplateDecl and its
45d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// derived classes.
46aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList {
47ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The location of the 'template' keyword.
48ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation TemplateLoc;
49ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
50ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The locations of the '<' and '>' angle brackets.
51ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation LAngleLoc, RAngleLoc;
52ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
53ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The number of template parameters in this template
54aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// parameter list.
556964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned NumParams : 31;
566964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
576964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// Whether this template parameter list contains an unexpanded parameter
586964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack.
596964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned ContainsUnexpandedParameterPack : 1;
60aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
61483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithprotected:
62ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
63bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                        NamedDecl **Params, unsigned NumParams,
64ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
66aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
674ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateParameterList *Create(const ASTContext &C,
68ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
69ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
70bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                                       NamedDecl **Params,
71ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
72ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
73aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
74d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Iterates through the template parameters in this list.
75bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl** iterator;
76aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
77d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Iterates through the template parameters in this list.
78bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl* const* const_iterator;
79aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
80bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
81aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
82bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor    return reinterpret_cast<NamedDecl * const *>(this + 1);
83aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
84aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator end() { return begin() + NumParams; }
85aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator end() const { return begin() + NumParams; }
86aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
87aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned size() const { return NumParams; }
88ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
895a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  llvm::ArrayRef<NamedDecl*> asArray() {
905a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    return llvm::ArrayRef<NamedDecl*>(begin(), size());
915a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
925a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  llvm::ArrayRef<const NamedDecl*> asArray() const {
935a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    return llvm::ArrayRef<const NamedDecl*>(begin(), size());
945a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
955a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
96bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  NamedDecl* getParam(unsigned Idx) {
97f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
98f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    return begin()[Idx];
99f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  }
100f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
101bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  const NamedDecl* getParam(unsigned Idx) const {
10240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
10340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return begin()[Idx];
10440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
10540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
106910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Returns the minimum number of arguments needed to form a
107d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// template specialization.
108d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  ///
109d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// This may be fewer than the number of template parameters, if some of
110d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// the parameters have default arguments or if there is a parameter pack.
11162cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  unsigned getMinRequiredArguments() const;
11262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
113ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Get the depth of this template parameter list in the set of
114ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template parameter lists.
115ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
116ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The first template parameter list in a declaration will have depth 0,
117ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// the second template parameter list will have depth 1, etc.
118ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
119ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1206964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Determine whether this template parameter list contains an
1216964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// unexpanded parameter pack.
1226964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool containsUnexpandedParameterPack() const {
1236964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return ContainsUnexpandedParameterPack;
1246964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
1256964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
126ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getTemplateLoc() const { return TemplateLoc; }
127ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getLAngleLoc() const { return LAngleLoc; }
128ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getRAngleLoc() const { return RAngleLoc; }
12962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
130aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY {
13162cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor    return SourceRange(TemplateLoc, RAngleLoc);
13262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  }
133aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
134aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
135d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Stores a list of template parameters for a TemplateDecl and its
136d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// derived classes. Suitable for creating on the stack.
137483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithtemplate<size_t N>
138483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithclass FixedSizeTemplateParameterList : public TemplateParameterList {
139483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  NamedDecl *Params[N];
140483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
141483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smithpublic:
142ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  FixedSizeTemplateParameterList(SourceLocation TemplateLoc,
143ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                                 SourceLocation LAngleLoc,
144483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith                                 NamedDecl **Params, SourceLocation RAngleLoc) :
145483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith    TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) {
146483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  }
147483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith};
148483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
149127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A template argument list.
150127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentList {
151127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template argument list.
152127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
153127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// The integer value will be non-zero to indicate that this
15456ef550c5eeea0714c635782776389df2a177584Chris Lattner  /// template argument list does own the pointer.
155910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> Arguments;
1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
157127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in this template
158127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument list.
159910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  unsigned NumArguments;
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
161be2fa7ebf01259b63dc52fe46c8d101c18e72269Craig Topper  TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
162be2fa7ebf01259b63dc52fe46c8d101c18e72269Craig Topper  void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
163910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
164910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs,
165910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                       bool Owned)
166910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    : Arguments(Args, Owned), NumArguments(NumArgs) { }
167910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
168aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
169ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Type used to indicate that the template argument list itself is a
170910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// stack object. It does not own its template arguments.
171910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  enum OnStackType { OnStack };
172910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
173910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Create a new template argument list that copies the given set of
174910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// template arguments.
175910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  static TemplateArgumentList *CreateCopy(ASTContext &Context,
176910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                          const TemplateArgument *Args,
177910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                          unsigned NumArgs);
178910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
179910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Construct a new, temporary template argument list on the stack.
180910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  ///
181910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// The template argument list does not own the template arguments
182910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// provided.
183ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  explicit TemplateArgumentList(OnStackType,
184910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                const TemplateArgument *Args, unsigned NumArgs)
185910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    : Arguments(Args, false), NumArguments(NumArgs) { }
186ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
187ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Produces a shallow copy of the given template argument list.
188ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ///
189910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// This operation assumes that the input argument list outlives it.
190910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// This takes the list as a pointer to avoid looking like a copy
191910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// constructor, since this really really isn't safe to use that
192910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// way.
193910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  explicit TemplateArgumentList(const TemplateArgumentList *Other)
194910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    : Arguments(Other->data(), false), NumArguments(Other->size()) { }
1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
196127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument &get(unsigned Idx) const {
198910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    assert(Idx < NumArguments && "Invalid template argument index");
199910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return data()[Idx];
200127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2055a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// \brief Produce this as an array ref.
2065a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  llvm::ArrayRef<TemplateArgument> asArray() const {
2075a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    return llvm::ArrayRef<TemplateArgument>(data(), size());
2085a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
2095a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
210127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in this
211127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list.
212910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  unsigned size() const { return NumArguments; }
2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
214910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Retrieve a pointer to the template argument list.
215910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  const TemplateArgument *data() const {
216910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return Arguments.getPointer();
217127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
218127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
220127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
221127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Templates
222127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
223aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
224d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief The base class of all kinds of template declarations (e.g.,
225d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// class, function, etc.).
226d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
227d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// The TemplateDecl class stores the list of template parameters and a
228d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// reference to the templated scoped declaration: the underlying AST node.
229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateDecl : public NamedDecl {
23099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
231127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // This is probably never used.
233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
234127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name)
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
236d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
237127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with the given name and parameters.
238127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
239127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
240127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
242d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
243127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
244127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
245127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
246127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               NamedDecl *Decl)
247127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
248127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParams(Params) { }
249127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
250127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the list of template parameters
251127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
252127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
253d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
254d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
255127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
256127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
257127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
258aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
25980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
26080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
2619a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstTemplate && K <= lastTemplate;
26280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  }
263aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
264aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY {
26580484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor    return SourceRange(TemplateParams->getTemplateLoc(),
26680484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor                       TemplatedDecl->getSourceRange().getEnd());
26780484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor  }
26880484d0de0dccee66d9f1760127c3e6e218987daDouglas Gregor
269127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
270127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
271127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
272ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2738731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidispublic:
2748731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Initialize the underlying templated declaration and
2758731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// template parameters.
2768731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
2778731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
2788731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    assert(TemplateParams == 0 && "TemplateParams already set!");
2798731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplatedDecl = templatedDecl;
2808731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis    TemplateParams = templateParams;
2818731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  }
282127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
2831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Provides information about a function template specialization,
285127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
286127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
287127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
288a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  FunctionTemplateSpecializationInfo(FunctionDecl *FD,
289a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     FunctionTemplateDecl *Template,
290a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     TemplateSpecializationKind TSK,
291a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     const TemplateArgumentList *TemplateArgs,
29271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis                       const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
293a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis                                     SourceLocation POI)
294a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  : Function(FD),
295a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    Template(Template, TSK - 1),
296a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArguments(TemplateArgs),
297a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    TemplateArgumentsAsWritten(TemplateArgsAsWritten),
298a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis    PointOfInstantiation(POI) { }
299a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
300127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
301a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  static FunctionTemplateSpecializationInfo *
302a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis  Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
303a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         TemplateSpecializationKind TSK,
304a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentList *TemplateArgs,
305a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis         const TemplateArgumentListInfo *TemplateArgsAsWritten,
30671a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis         SourceLocation POI);
307a626a3d0fb74455651f742c0938902a42e6e71c8Argyrios Kyrtzidis
3081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template specialization that this structure
309127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
310127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template from which this function template
313127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
3141fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
315d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
316d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
318127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
319127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
320127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
3211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
322e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara  /// \brief The template arguments as written in the sources, if provided.
32371a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
324e03db98d67111ebf7622d9086951aacc24406b66Abramo Bagnara
325b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief The point at which this function template specialization was
326ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// first instantiated.
327b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
328ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
3291fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
3301fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
331d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
332d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Determine what kind of template specialization this is.
333d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
334d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    return (TemplateSpecializationKind)(Template.getInt() + 1);
335d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  }
336d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
3376ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  bool isExplicitSpecialization() const {
3386ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
3396ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  }
3406ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall
3415a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// \brief True if this declaration is an explicit specialization,
3425a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// explicit instantiation declaration, or explicit instantiation
3435a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// definition.
3445a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  bool isExplicitInstantiationOrSpecialization() const {
3455a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    switch (getTemplateSpecializationKind()) {
3465a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitSpecialization:
3475a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDeclaration:
3485a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDefinition:
3495a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return true;
3505a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
3515a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_Undeclared:
3525a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ImplicitInstantiation:
3535a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return false;
3545a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    }
3555a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    llvm_unreachable("bad template specialization kind");
3565a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
3575a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
358d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Set the template specialization kind.
359d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(TSK != TSK_Undeclared &&
361d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor         "Cannot encode TSK_Undeclared for a function template specialization");
362d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    Template.setInt(TSK - 1);
3631fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
365b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Retrieve the first point of instantiation of this function
366b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// template specialization.
367b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  ///
368b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// The point of instantiation may be an invalid source location if this
369b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// function has yet to be instantiated.
370ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getPointOfInstantiation() const {
371ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    return PointOfInstantiation;
372b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
373ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
374b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the (first) point of instantiation of this function template
375b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// specialization.
376b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
377b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
378b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
379ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
380127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
381910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    Profile(ID, TemplateArguments->data(),
382910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor            TemplateArguments->size(),
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Function->getASTContext());
384127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
388828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
389127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
390127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
391828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
3921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
393127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
395ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie/// \brief Provides information a specialization of a member of a class
396f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith/// template, which may be a member function, static data member,
397f1c66b40213784a1c4612f04c14cafa2b0e89988Richard Smith/// member class or member enumeration.
3982db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorclass MemberSpecializationInfo {
39944e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // The member declaration from which this member was instantiated, and the
40044e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  // manner in which the instantiation occurred (in the lower two bits).
40144e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
402ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
403b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  // The point at which this member was first instantiated.
404b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  SourceLocation PointOfInstantiation;
405ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4062db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregorpublic:
407ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  explicit
4089421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
4099421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis                           SourceLocation POI = SourceLocation())
4109421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
411ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    assert(TSK != TSK_Undeclared &&
41244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
41344e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  }
414ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4152db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Retrieve the member declaration from which this member was
4162db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// instantiated.
41744e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
418ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4192db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Determine what kind of template specialization this is.
4202db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
42144e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
4222db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
423ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4243892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall  bool isExplicitSpecialization() const {
4253892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
4263892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall  }
4273892d022f36ee5bf3be4a55ea01c08d323ef6235John McCall
4282db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  /// \brief Set the template specialization kind.
4292db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
430ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    assert(TSK != TSK_Undeclared &&
43144e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor           "Cannot encode undeclared template specializations for members");
43244e368b6a85c42d681148ccd5e0052418ff9751eDouglas Gregor    MemberAndTSK.setInt(TSK - 1);
4332db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor  }
434ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
435ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieve the first point of instantiation of this member.
436b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// If the point of instantiation is an invalid location, then this member
437b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// has not yet been instantiated.
438ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  SourceLocation getPointOfInstantiation() const {
439ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    return PointOfInstantiation;
440b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
441ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
442b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  /// \brief Set the first point of instantiation.
443b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  void setPointOfInstantiation(SourceLocation POI) {
444b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor    PointOfInstantiation = POI;
445b3ae4fcd4314a9c1c46d41b200883599c32025b4Douglas Gregor  }
4462db323294ac02296125e1e0beb4c3595992e75bbDouglas Gregor};
447af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
448af2094e7cecadf36667deb61a83587ffdd979bd3John McCall/// \brief Provides information about a dependent function-template
449d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// specialization declaration.
450d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
451d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// Since explicit function template specialization and instantiation
452d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// declarations can only appear in namespace scope, and you can only
453d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// specialize a member of a fully-specialized class, the only way to
454d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// get one of these is in a friend declaration like the following:
455af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///
456d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
457d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<class T> void foo(T);
458d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<class T> class A {
459af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///     friend void foo<>(T);
460af2094e7cecadf36667deb61a83587ffdd979bd3John McCall///   };
461d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
462af2094e7cecadf36667deb61a83587ffdd979bd3John McCallclass DependentFunctionTemplateSpecializationInfo {
463e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct CA {
464e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    /// The number of potential template candidates.
465e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned NumTemplates;
466e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
467e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    /// The number of template arguments.
468e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned NumArgs;
469e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
470e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
471af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  union {
472af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // Force sizeof to be a multiple of sizeof(void*) so that the
473af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    // trailing data is aligned.
474ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie    void *Aligner;
475e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct CA d;
476af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  };
477af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
478af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// The locations of the left and right angle brackets.
479af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceRange AngleLocs;
480af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
481af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl * const *getTemplates() const {
482af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
483af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
484af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
485af2094e7cecadf36667deb61a83587ffdd979bd3John McCallpublic:
486af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  DependentFunctionTemplateSpecializationInfo(
487af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const UnresolvedSetImpl &Templates,
488af2094e7cecadf36667deb61a83587ffdd979bd3John McCall                                 const TemplateArgumentListInfo &TemplateArgs);
489af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
490af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of function templates that this might
491af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// be a specialization of.
492af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplates() const {
493af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumTemplates;
494af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
495af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
496af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the i'th template candidate.
497af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  FunctionTemplateDecl *getTemplate(unsigned I) const {
498af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplates() && "template index out of range");
499af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplates()[I];
500af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
501af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
502e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  /// \brief Returns the explicit template arguments that were given.
503e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  const TemplateArgumentLoc *getTemplateArgs() const {
504e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor    return reinterpret_cast<const TemplateArgumentLoc*>(
505ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                                            &getTemplates()[getNumTemplates()]);
506e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  }
507e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor
508af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the number of explicit template arguments that were given.
509af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  unsigned getNumTemplateArgs() const {
510af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return d.NumArgs;
511af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
512af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
513af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  /// \brief Returns the nth template argument.
514af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
515af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    assert(I < getNumTemplateArgs() && "template arg index out of range");
516af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return getTemplateArgs()[I];
517af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
518af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
519af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getLAngleLoc() const {
520af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getBegin();
521af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
522af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
523af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  SourceLocation getRAngleLoc() const {
524af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return AngleLocs.getEnd();
525af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
526af2094e7cecadf36667deb61a83587ffdd979bd3John McCall};
527ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
5289eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a redeclarable template.
5297c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass RedeclarableTemplateDecl : public TemplateDecl,
5307c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor                                 public Redeclarable<RedeclarableTemplateDecl>
5317c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor{
5327c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
5337c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  virtual RedeclarableTemplateDecl *getNextRedeclaration() {
5347c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return RedeclLink.getNext();
5359eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
536ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  virtual RedeclarableTemplateDecl *getPreviousDeclImpl() {
537ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getPreviousDecl();
538ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
539ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  virtual RedeclarableTemplateDecl *getMostRecentDeclImpl() {
540ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return getMostRecentDecl();
541ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  }
5421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
54444dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  template <typename EntryType> struct SpecEntryTraits {
54544dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    typedef EntryType DeclType;
54644dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
547ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    static DeclType *getMostRecentDecl(EntryType *D) {
548ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      return D->getMostRecentDecl();
54944dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne    }
55044dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  };
55144dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
5529f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType,
5539f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _SETraits = SpecEntryTraits<EntryType>,
5549f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne            typename _DeclType = typename _SETraits::DeclType>
5559f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  class SpecIterator : public std::iterator<std::forward_iterator_tag,
5569f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, ptrdiff_t,
5579f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne                                            _DeclType*, _DeclType*> {
5589f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _SETraits SETraits;
5599f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    typedef _DeclType DeclType;
5609f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
561d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    typedef typename llvm::FoldingSetVector<EntryType>::iterator
562d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth      SetIteratorType;
5639f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5649f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SetIteratorType SetIter;
5659f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5669f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  public:
5679f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator() : SetIter() {}
5689f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
5699f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5709f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator*() const {
571ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      return SETraits::getMostRecentDecl(&*SetIter);
5729f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5739f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    DeclType *operator->() const { return **this; }
5749f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5759f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator &operator++() { ++SetIter; return *this; }
5769f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    SpecIterator operator++(int) {
5779f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      SpecIterator tmp(*this);
5789f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      ++(*this);
5799f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return tmp;
5809f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5819f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5829f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator==(SpecIterator Other) const {
5839f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter == Other.SetIter;
5849f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5859f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    bool operator!=(SpecIterator Other) const {
5869f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne      return SetIter != Other.SetIter;
5879f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    }
5889f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  };
5899f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5909f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  template <typename EntryType>
591e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  static SpecIterator<EntryType>
592d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
5939f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
5949f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
5959f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
5964048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne  template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
597d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
5984048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne                         const TemplateArgument *Args, unsigned NumArgs,
5994048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne                         void *&InsertPos);
6004048590d5774fd4b08661b5cf59b6f90b62f283aPeter Collingbourne
6019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct CommonBase {
6029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    CommonBase() : InstantiatedFromMember(0, false) { }
6039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
6049eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// \brief The template from which this was most
605d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// directly instantiated (or null).
606fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    ///
6079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// The boolean value indicates whether this template
608fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor    /// was explicitly specialized.
6099eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
6109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne      InstantiatedFromMember;
6113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
6121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6137c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  /// \brief Pointer to the common data shared by all declarations of this
6147c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  /// template.
615b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  mutable CommonBase *Common;
6167c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor
6179eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
6189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// the same template. Calling this routine may implicitly allocate memory
6199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// for the common pointer.
620b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  CommonBase *getCommonPtr() const;
6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
622b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  virtual CommonBase *newCommon(ASTContext &C) const = 0;
6232c853e401ca406d417eb916e867226050e7be06bArgyrios Kyrtzidis
6249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  // Construct a template decl with name, parameters, and templated element.
6259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
6269eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                           DeclarationName Name, TemplateParameterList *Params,
6279eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                           NamedDecl *Decl)
6287c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { }
6291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
6319eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  template <class decl_type> friend class RedeclarableTemplate;
6329eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
633d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Retrieves the canonical declaration of this template.
6347c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDeclaration(); }
6357c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  const RedeclarableTemplateDecl *getCanonicalDecl() const {
6367c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return getFirstDeclaration();
637ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis  }
638ba5ff8ccf3f2a4d8fa3e91b58733707fb1caed6bArgyrios Kyrtzidis
639ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Determines whether this template was a specialization of a
6409eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// member template.
6419eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// In the following example, the function template \c X<int>::f and the
6439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// member template \c X<int>::Inner are member specializations.
6449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \code
6469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<typename T>
6479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// struct X {
6489eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template<typename U> void f(T, U);
6499eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///   template<typename U> struct Inner;
6509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// };
6519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ///
6529eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<> template<typename T>
6539eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// void X<int>::f(int, T);
6549eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// template<> template<typename T>
6559eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// struct X<int>::Inner { /* ... */ };
6569eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \endcode
657b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  bool isMemberSpecialization() const {
6589eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return getCommonPtr()->InstantiatedFromMember.getInt();
6599eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
660ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
6619eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Note that this member template is a specialization.
6629eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  void setMemberSpecialization() {
6639eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
6649eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne           "Only member templates can be member template specializations");
6659eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    getCommonPtr()->InstantiatedFromMember.setInt(true);
6669eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
667ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
6680f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \brief Retrieve the member template from which this template was
6690f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// instantiated, or NULL if this template was not instantiated from a
6700f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// member template.
6710f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6720f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// A template is instantiated from a member template when the member
6730f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template itself is part of a class template (or member thereof). For
6740f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// example, given
6750f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6760f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \code
6770f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename T>
6780f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// struct X {
6790f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///   template<typename U> void f(T, U);
6800f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// };
6810f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6820f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// void test(X<int> x) {
6830f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///   x.f(1, 'a');
6840f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// };
6850f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \endcode
6860f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6870f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \c X<int>::f is a FunctionTemplateDecl that describes the function
6880f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template
6890f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6900f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \code
6910f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename U> void X<int>::f(int, U);
6920f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \endcode
6930f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6940f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// which was itself created during the instantiation of \c X<int>. Calling
6950f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
696d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// retrieve the FunctionTemplateDecl for the original template \c f within
6970f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// the class template \c X<T>, i.e.,
6980f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  ///
6990f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \code
7000f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename T>
7010f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// template<typename U>
7020f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// void X<T>::f(T, U);
7030f5897bf5f919df28c76013d1efa17441f7241ffDouglas Gregor  /// \endcode
704b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
7057c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return getCommonPtr()->InstantiatedFromMember.getPointer();
7067c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  }
7077c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor
7087c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
7097c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
7107c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    getCommonPtr()->InstantiatedFromMember.setPointer(TD);
7119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7129eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
713a54fbf2499c7cc999e22abb9be484ce976ed9689Douglas Gregor  typedef redeclarable_base::redecl_iterator redecl_iterator;
714ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_begin;
715ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::redecls_end;
716ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getPreviousDecl;
717ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  using redeclarable_base::getMostRecentDecl;
718f785a7d611404cf4747287a2bbc59b4d0e6a5a8cDouglas Gregor
7199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  // Implement isa/cast/dyncast/etc.
7209eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
7219eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static bool classofKind(Kind K) {
7229eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
7239eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
7249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7257c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor  friend class ASTReader;
726d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
7273397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
7289eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne};
7299eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
73044dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbournetemplate <> struct RedeclarableTemplateDecl::
73144dd0b440efdb37ff4c6e49f243faa3b0580b120Peter CollingbourneSpecEntryTraits<FunctionTemplateSpecializationInfo> {
73244dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  typedef FunctionDecl DeclType;
73344dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
73444dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  static DeclType *
735ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  getMostRecentDecl(FunctionTemplateSpecializationInfo *I) {
736ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor    return I->Function->getMostRecentDecl();
73744dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne  }
73844dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne};
73944dd0b440efdb37ff4c6e49f243faa3b0580b120Peter Collingbourne
7409eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne/// Declaration of a template function.
7417c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass FunctionTemplateDecl : public RedeclarableTemplateDecl {
7429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  static void DeallocateCommon(void *Ptr);
7439eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourneprotected:
7459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Data that is common to all of the declarations of a given
7469eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
7479eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
7486982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    Common() : InjectedArgs(), LazySpecializations() { }
749ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
7509eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// \brief The function template specializations for this function
7519eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    /// template, including explicit specializations and instantiations.
752d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
753ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
754c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// \brief The set of "injected" template arguments used within this
755c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// function template.
756c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    ///
757c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// This pointer refers to the template arguments (there are as
758c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// many template arguments as template parameaters) for the function
759c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// template, and is allocated lazily, since most function templates do not
760c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    /// require the use of this information.
761c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor    TemplateArgument *InjectedArgs;
7626982bf4d77bc57a85ee173b631729fce673f16efRichard Smith
7636982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// \brief If non-null, points to an array of specializations known only
7646982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// by their external declaration IDs.
7656982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    ///
7666982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// The first value in the array is the number of of specializations
7676982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// that follow.
7686982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    uint32_t *LazySpecializations;
7699eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  };
7709eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7719eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
7729eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                       TemplateParameterList *Params, NamedDecl *Decl)
7739eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
7749eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
775b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  CommonBase *newCommon(ASTContext &C) const;
7769eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
777e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  Common *getCommonPtr() const {
7789eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
779fd056bc86a8b22a9421b5d921bbca276d0f9d0f7Douglas Gregor  }
7809eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
7816b5415196327fa8ef00f028ba175fafef1738ae1Argyrios Kyrtzidis  friend class FunctionDecl;
782da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor
7836982bf4d77bc57a85ee173b631729fce673f16efRichard Smith  /// \brief Load any lazily-loaded specializations from the external source.
7846982bf4d77bc57a85ee173b631729fce673f16efRichard Smith  void LoadLazySpecializations() const;
7856982bf4d77bc57a85ee173b631729fce673f16efRichard Smith
7869eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the set of function template specializations of this
7879eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// function template.
788d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
7896982bf4d77bc57a85ee173b631729fce673f16efRichard Smith  getSpecializations() const;
7905bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl
7915bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  /// \brief Add a specialization of this function template.
7925bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  ///
793d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  /// \param InsertPos Insert position in the FoldingSetVector, must have been
7945bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  ///        retrieved by an earlier call to findSpecialization().
7955bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl  void addSpecialization(FunctionTemplateSpecializationInfo* Info,
7965bbcdbf36f8cf79d99703ef20848c55960065e43Sebastian Redl                         void *InsertPos);
797ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
7989eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbournepublic:
7999eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// Get the underlying function declaration of the template.
8009eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionDecl *getTemplatedDecl() const {
8019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<FunctionDecl*>(TemplatedDecl);
8029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
80413fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// Returns whether this template declaration defines the primary
80513fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// pattern.
80613fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
80713fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
80813fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
80913fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
8109eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Return the specialization with the provided arguments if it exists,
8119eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// otherwise return the insertion point.
8129eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionDecl *findSpecialization(const TemplateArgument *Args,
8139eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne                                   unsigned NumArgs, void *&InsertPos);
8149eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8159eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getCanonicalDecl() {
8167c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<FunctionTemplateDecl>(
8177c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
8189eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8199eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const FunctionTemplateDecl *getCanonicalDecl() const {
8207c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<FunctionTemplateDecl>(
8217c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
8229eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8239eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8249eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this function template, or
8259eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
826ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  FunctionTemplateDecl *getPreviousDecl() {
8277c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<FunctionTemplateDecl>(
828ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor             RedeclarableTemplateDecl::getPreviousDecl());
8299eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8309eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8319eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this function template, or
8329eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
833ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  const FunctionTemplateDecl *getPreviousDecl() const {
8347c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<FunctionTemplateDecl>(
835ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor             RedeclarableTemplateDecl::getPreviousDecl());
8369eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8379eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8389eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
8397c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<FunctionTemplateDecl>(
8407c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
8419eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
8429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
8439f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
8449f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
845e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_begin() const {
8469f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
8479f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8489f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
849e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_end() const {
8509f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
8519f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
8529f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
853c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// \brief Retrieve the "injected" template arguments that correspond to the
854c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// template parameters of this function template.
855ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ///
856c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// Although the C++ standard has no notion of the "injected" template
857c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// arguments for a function template, the notion is convenient when
858c494f77363f057dd8619fec4e885c4f80e3d1b66Douglas Gregor  /// we need to perform substitutions inside the definition of a function
859ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// template.
8607a9f7c7c68673c46d6e2b83fec6f4cbfbd25f475Richard Smith  ArrayRef<TemplateArgument> getInjectedTemplateArgs();
861ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
8629a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  /// \brief Create a function template node.
863127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
864127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
865127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
866127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
867127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
8683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
8699a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  /// \brief Create an empty function template node.
8701e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
8719a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
872127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
87380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
87480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == FunctionTemplate; }
875c8f9af2943699ff623ca08f2e5ed4d72e0351189Argyrios Kyrtzidis
876d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
8773397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
878127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
879d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
880127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
881127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
882127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
88340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
884d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Defines the position of a template parameter within a template
885d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// parameter list.
886d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
887d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// Because template parameter can be listed
888127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
889127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
890127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
891127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
892127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
8931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass TemplateParmPosition {
894127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
895127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
896127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
897127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
898b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie  { /* llvm_unreachable("Cannot create positionless template parameter"); */ }
8993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
900127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
901127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
902127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
9033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
904127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
905127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
906127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
907127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
9083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
909127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
910127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
911127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
912b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setDepth(unsigned D) { Depth = D; }
9133e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
914127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
915127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
916b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  void setPosition(unsigned P) { Position = P; }
9171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
918127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
919127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
920127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
9213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
922d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of a template type parameter.
923d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
924d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// For example, "T" in
925d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
926127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
927d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
928127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
929127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
930d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// the 'typename' keyword.
931d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  ///
932d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// If false, it was declared with the 'class' keyword.
933127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
9343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
935127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
936127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
937127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
9383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
939127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
940a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *DefaultArgument;
941127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
942344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara  TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
943344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                       SourceLocation IdLoc, IdentifierInfo *Id,
9444fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth                       bool Typename)
945344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara    : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
9464fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth      InheritedDefault(false), DefaultArgument() { }
9473e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
948483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  /// Sema creates these on the stack during auto type deduction.
949483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith  friend class Sema;
950483b9f3bc05c5409e2c6643f1c9d91e21c8ff9d2Richard Smith
951127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
9524ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
953344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      SourceLocation KeyLoc,
954344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      SourceLocation NameLoc,
955344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara                                      unsigned D, unsigned P,
956127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
957127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
9581e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
9591e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                  unsigned ID);
960c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
961127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
962d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// the 'typename' keyword.
963d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  ///
964d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// If not, it was declared with the 'class' keyword.
965127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
966c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
967127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
968127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
969833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  bool hasDefaultArgument() const { return DefaultArgument != 0; }
970199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
971127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
972833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
97340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
974833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the default argument's source information, if any.
975a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
976833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
977833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Retrieves the location of the default argument declaration.
978833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  SourceLocation getDefaultArgumentLoc() const;
97940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
980127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
981127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
982127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
983f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
984127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
985127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
986127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
987a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
988127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
989127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
990f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
99140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
992833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Removes the default argument of this template parameter.
993833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  void removeDefaultArgument() {
994833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    DefaultArgument = 0;
995833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    InheritedDefault = false;
996833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
997ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
9988731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// \brief Set whether this template type parameter was declared with
9998731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  /// the 'typename' or 'class' keyword.
10008731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
10018731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis
1002ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the depth of the template parameter.
1003ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getDepth() const;
1004ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1005ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the index of the template parameter.
1006ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  unsigned getIndex() const;
1007ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor
1008127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
10094fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth  bool isParameterPack() const;
1010fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
1011aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
101277d4ee2bfc90b77ec8b818de985cd4aceeef757bAbramo Bagnara
1013127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
101480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
101580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
10163e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
10173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1018127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1019127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
1020127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1021127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
1022127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1023127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
102476a40219ee5624d78aba167dce02bdbaa930955fJohn McCall  : public DeclaratorDecl, protected TemplateParmPosition {
1025d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief The default template argument, if any, and whether or not
1026d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// it was inherited.
1027d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
1028127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
102910738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
103010738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  // down here to save memory.
1031ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
103210738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \brief Whether this non-type template parameter is a parameter pack.
103310738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  bool ParameterPack;
1034ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1035ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Whether this non-type template parameter is an "expanded"
10366952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// parameter pack, meaning that its type is a pack expansion and we
10376952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// already know the set of types that expansion expands to.
10386952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  bool ExpandedParameterPack;
1039ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
10406952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief The number of types in an expanded parameter pack.
10416952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  unsigned NumExpandedTypes;
1042ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1043ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1044ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          SourceLocation IdLoc, unsigned D, unsigned P,
1045ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          IdentifierInfo *Id, QualType T,
104610738d36b150aa65206890c1c845cdba076e4200Douglas Gregor                          bool ParameterPack, TypeSourceInfo *TInfo)
1047ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
104810738d36b150aa65206890c1c845cdba076e4200Douglas Gregor      TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
10496952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      ParameterPack(ParameterPack), ExpandedParameterPack(false),
10506952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      NumExpandedTypes(0)
1051127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
1052127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1053ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1054ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          SourceLocation IdLoc, unsigned D, unsigned P,
1055ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara                          IdentifierInfo *Id, QualType T,
10566952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          TypeSourceInfo *TInfo,
10576952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          const QualType *ExpandedTypes,
10586952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          unsigned NumExpandedTypes,
10596952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                          TypeSourceInfo **ExpandedTInfos);
10606952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
106110738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  friend class ASTDeclReader;
1062ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
10631c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
1064127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
1065ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1066ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1067ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
10689ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
10696952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  static NonTypeTemplateParmDecl *
1070ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1071ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1072ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara         QualType T, TypeSourceInfo *TInfo,
10736952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor         const QualType *ExpandedTypes, unsigned NumExpandedTypes,
10746952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor         TypeSourceInfo **ExpandedTInfos);
10756952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
10761e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
10771e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned ID);
10781e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
10791e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned ID,
10801e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                     unsigned NumExpandedTypes);
10811e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1082127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1083b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setDepth;
1084127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1085b24e199fbd17af780ab000c5862d191e4daffc0fArgyrios Kyrtzidis  using TemplateParmPosition::setPosition;
1086127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
10871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1088aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
108976a40219ee5624d78aba167dce02bdbaa930955fJohn McCall
1090127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1091127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1092d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
1093d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer() != 0;
1094d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1095fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
1096127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1097d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  Expr *getDefaultArgument() const {
1098d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getPointer();
1099d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1100127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1101127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
1102127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
1103127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
1104d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1105d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1106d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1107d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentAndInherited.getInt();
1108d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1109d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1110d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1111d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1112d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1113d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(Expr *DefArg, bool Inherited) {
1114d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(DefArg);
1115d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(Inherited);
1116d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1117d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1118d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1119d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
1120d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setPointer(0);
1121d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentAndInherited.setInt(false);
11223b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
1123127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
112410738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \brief Whether this parameter is a non-type template parameter pack.
112510738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  ///
112610738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// If the parameter is a parameter pack, the type may be a
112710738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \c PackExpansionType. In the following example, the \c Dims parameter
112810738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// is a parameter pack (whose type is 'unsigned').
112910738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  ///
113010738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \code
113110738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// template<typename T, unsigned ...Dims> struct multi_array;
113210738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  /// \endcode
113310738d36b150aa65206890c1c845cdba076e4200Douglas Gregor  bool isParameterPack() const { return ParameterPack; }
1134ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
11356964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this parameter pack is a pack expansion.
11366964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
11376964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// A non-type template parameter pack is a pack expansion if its type
11386964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// contains an unexpanded parameter pack. In this case, we will have
11396964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// built a PackExpansionType wrapping the type.
11406964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool isPackExpansion() const {
11416964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return ParameterPack && getType()->getAs<PackExpansionType>();
11426964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
11436964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
11446952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \brief Whether this parameter is a non-type template parameter pack
11456964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// that has a known list of different types at different positions.
11466952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11476952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// A parameter pack is an expanded parameter pack when the original
11486952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// parameter pack's type was itself a pack expansion, and that expansion
11496952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// has already been expanded. For example, given:
11506952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
11516952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \code
11526952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// template<typename ...Types>
11536952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// struct X {
11546952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///   template<Types ...Values>
11556952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///   struct Y { /* ... */ };
11566952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// };
11576952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \endcode
1158ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  ///
11596952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// The parameter pack \c Values has a \c PackExpansionType as its type,
11606952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// which expands \c Types. When \c Types is supplied with template arguments
1161ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// by instantiating \c X, the instantiation of \c Values becomes an
1162ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// expanded parameter pack. For example, instantiating
11636952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// \c X<int, unsigned int> results in \c Values being an expanded parameter
11646952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// pack with expansion types \c int and \c unsigned int.
11656952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  ///
1166ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
11676952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// return the expansion types.
11686952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1169ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1170ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieves the number of expansion types in an expanded parameter
1171ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// pack.
11726952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  unsigned getNumExpansionTypes() const {
11736952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(ExpandedParameterPack && "Not an expansion parameter pack");
11746952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return NumExpandedTypes;
11756952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11766952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1177ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieve a particular expansion type within an expanded parameter
11786952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// pack.
11796952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  QualType getExpansionType(unsigned I) const {
11806952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
11816952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
11826952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return QualType::getFromOpaquePtr(TypesAndInfos[2*I]);
11836952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11846952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1185ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Retrieve a particular expansion type source info within an
11866952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// expanded parameter pack.
11876952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
11886952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
11896952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
11906952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]);
11916952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
11926952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
1193127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
119480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
119580cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
11961c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
11971c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
1198127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
1199127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
1200127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
1201127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
1202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
1203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
1204127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
12051e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregorclass TemplateTemplateParmDecl : public TemplateDecl,
12061e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                 protected TemplateParmPosition
12071e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor{
120899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
12097e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1210d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// DefaultArgument - The default template argument, if any.
1211788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  TemplateArgumentLoc DefaultArgument;
1212d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// Whether or not the default argument was inherited.
1213d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool DefaultArgumentWasInherited;
12147e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
121561c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  /// \brief Whether this parameter is a parameter pack.
121661c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  bool ParameterPack;
1217ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
12186964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this template template parameter is an "expanded"
12196964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// parameter pack, meaning that it is a pack expansion and we
12206964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// already know the set of template parameters that expansion expands to.
12216964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool ExpandedParameterPack;
12226964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
12236964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief The number of parameters in an expanded parameter pack.
12246964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned NumExpandedParams;
12256964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
1226127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
122761c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                           unsigned D, unsigned P, bool ParameterPack,
1228127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
1229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1230d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara      TemplateParmPosition(D, P), DefaultArgument(),
12316964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith      DefaultArgumentWasInherited(false), ParameterPack(ParameterPack),
12326964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith      ExpandedParameterPack(false), NumExpandedParams(0)
1233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
12347e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
12356964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
12366964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           unsigned D, unsigned P,
12376964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           IdentifierInfo *Id, TemplateParameterList *Params,
12386964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           unsigned NumExpansions,
12396964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                           TemplateParameterList * const *Expansions);
12406964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
1241127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
12424ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
1243127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
124461c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                                          unsigned P, bool ParameterPack,
124561c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor                                          IdentifierInfo *Id,
1246127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
12476964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
12486964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          SourceLocation L, unsigned D,
12496964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          unsigned P,
12506964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          IdentifierInfo *Id,
12516964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                          TemplateParameterList *Params,
1252cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko                                 ArrayRef<TemplateParameterList *> Expansions);
12537e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
12546964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
12551e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor                                                      unsigned ID);
12566964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
12576964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                                      unsigned ID,
12586964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith                                                      unsigned NumExpansions);
12591e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
1260127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
1261127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
1262127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
12631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1264d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \brief Whether this template template parameter is a template
1265d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// parameter pack.
1266d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  ///
1267d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \code
1268d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// template<template <class T> ...MetaFunctions> struct Apply;
1269d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \endcode
127061c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  bool isParameterPack() const { return ParameterPack; }
1271d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
12726964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this parameter pack is a pack expansion.
12736964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12746964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// A template template parameter pack is a pack expansion if its template
12756964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// parameter list contains an unexpanded parameter pack.
12766964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool isPackExpansion() const {
12776964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return ParameterPack &&
12786964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith           getTemplateParameters()->containsUnexpandedParameterPack();
12796964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
12806964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
12816964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Whether this parameter is a template template parameter pack that
12826964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// has a known list of different template parameter lists at different
12836964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// positions.
12846964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12856964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// A parameter pack is an expanded parameter pack when the original parameter
12866964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack's template parameter list was itself a pack expansion, and that
12876964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// expansion has already been expanded. For exampe, given:
12886964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12896964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \code
12906964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// template<typename...Types> struct Outer {
12916964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///   template<template<Types> class...Templates> struct Inner;
12926964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// };
12936964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \endcode
12946964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  ///
12956964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// The parameter pack \c Templates is a pack expansion, which expands the
12966964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack \c Types. When \c Types is supplied with template arguments by
12976964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// instantiating \c Outer, the instantiation of \c Templates is an expanded
12986964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// parameter pack.
12996964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
13006964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
13016964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Retrieves the number of expansion template parameters in
13026964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// an expanded parameter pack.
13036964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  unsigned getNumExpansionTemplateParameters() const {
13046964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    assert(ExpandedParameterPack && "Not an expansion parameter pack");
13056964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return NumExpandedParams;
13066964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
13076964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
13086964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// \brief Retrieve a particular expansion type within an expanded parameter
13096964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  /// pack.
13106964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
13116964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    assert(I < NumExpandedParams && "Out-of-range expansion type index");
13126964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith    return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I];
13136964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith  }
13146964b3f80ce1ba489e7e25e7cd58062699af9b0cRichard Smith
1315127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
1316127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
1317d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool hasDefaultArgument() const {
1318d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return !DefaultArgument.getArgument().isNull();
1319788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
13207e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1321127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
1322d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  const TemplateArgumentLoc &getDefaultArgument() const {
1323d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgument;
1324d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1325d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1326d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Retrieve the location of the default argument, if any.
1327d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  SourceLocation getDefaultArgumentLoc() const;
1328d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1329d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Determines whether the default argument was inherited
1330d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// from a previous declaration of this template.
1331d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  bool defaultArgumentWasInherited() const {
1332d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    return DefaultArgumentWasInherited;
1333788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
13347e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1335d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Set the default argument for this template parameter, and
1336d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// whether that default argument was inherited from another
1337d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// declaration.
1338d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
1339127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
1340d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = Inherited;
1341d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  }
1342d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara
1343d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  /// \brief Removes the default argument of this template parameter.
1344d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara  void removeDefaultArgument() {
1345d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgument = TemplateArgumentLoc();
1346d92f7a297c0ed3f7d0ebcbb557e1d4c1925b8c72Abramo Bagnara    DefaultArgumentWasInherited = false;
1347127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
13487e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
1349aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY {
1350fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    SourceLocation End = getLocation();
1351fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    if (hasDefaultArgument() && !defaultArgumentWasInherited())
1352fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor      End = getDefaultArgument().getSourceRange().getEnd();
1353fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor    return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1354fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor  }
1355fe72e9ceeae6cc8669cd8bb722425300190638eaDouglas Gregor
1356127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
135780cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
135880cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1359bfcc92c3476ada55ceeea49e43e6d2e083252830Argyrios Kyrtzidis
1360d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
13613397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
13627e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
13637e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
13643e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
13653e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
13663e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
13673e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
13683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
13693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
13703e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
13713e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
13723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
13731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
13741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// template<>
13753e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
13763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
13771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplateSpecializationDecl
13783e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
13791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Structure that stores information about a class template
138137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
138237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
138337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
138437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
138537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
138637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
13871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
138837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
138937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
1390d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    const TemplateArgumentList *TemplateArgs;
139137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
13921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
139437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
139537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
13963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1397c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
1398c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  struct ExplicitSpecializationInfo {
1399c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The type-as-written.
1400c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    TypeSourceInfo *TypeAsWritten;
1401c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the extern keyword.
1402c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation ExternLoc;
1403c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    /// \brief The location of the template keyword.
1404c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    SourceLocation TemplateKeywordLoc;
1405c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1406c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitSpecializationInfo()
1407c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara      : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
1408c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  };
1409c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1410c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Further info for explicit template specialization/instantiation.
14113cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// Does not apply to implicit specializations.
1412c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  ExplicitSpecializationInfo *ExplicitInfo;
14133cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
14147e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
1415d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  const TemplateArgumentList *TemplateArgs;
1416cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
14179cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief The point where this template was instantiated (if any)
14189cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation PointOfInstantiation;
14199cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
1420cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
1421cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
1422d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  unsigned SpecializationKind : 3;
1423cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1424c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
142513c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
1426ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                  DeclContext *DC, SourceLocation StartLoc,
1427ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                  SourceLocation IdLoc,
14283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
1429910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                  const TemplateArgument *Args,
1430910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                  unsigned NumArgs,
14318e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
14321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
143394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  explicit ClassTemplateSpecializationDecl(Kind DK);
143494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
14353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
14363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
1437ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1438ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara         SourceLocation StartLoc, SourceLocation IdLoc,
14393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
1440910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         const TemplateArgument *Args,
1441910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         unsigned NumArgs,
1442cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
1443b8b03e6df1cc89e701a809c6a47c41f31b7a9e50Argyrios Kyrtzidis  static ClassTemplateSpecializationDecl *
14441e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  CreateDeserialized(ASTContext &C, unsigned ID);
144594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
14465eada844fa70b6e2bc941dd7306f7a4fb1e8529dBenjamin Kramer  virtual void getNameForDiagnostic(raw_ostream &OS,
1447da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor                                    const PrintingPolicy &Policy,
1448da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor                                    bool Qualified) const;
1449da2142f2e2b3a02ee6eb5de9f9e6ed6f7eb5a0c0Douglas Gregor
1450ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  ClassTemplateSpecializationDecl *getMostRecentDecl() {
1451cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    CXXRecordDecl *Recent
1452ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor        = cast<CXXRecordDecl>(CXXRecordDecl::getMostRecentDecl());
1453b60fae50d38a0291e1c5731b2fb22849d26ca342Richard Smith    while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
1454cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis      // FIXME: Does injected class name need to be in the redeclarations chain?
1455ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
1456ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor      Recent = Recent->getPreviousDecl();
1457cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    }
1458cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplateSpecializationDecl>(Recent);
1459cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1460cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
14613e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
146237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
14633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
14641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the template arguments of the class template
146537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
14661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgumentList &getTemplateArgs() const {
1467910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    return *TemplateArgs;
14683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
14693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1470cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
1471cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
1472cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
1473cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
1474cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1475cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
14766ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  bool isExplicitSpecialization() const {
14776ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall    return getSpecializationKind() == TSK_ExplicitSpecialization;
14786ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall  }
14796ce51ee94bd300c5f30930d96436fd53e4ea89a7John McCall
14805a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// \brief True if this declaration is an explicit specialization,
14815a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// explicit instantiation declaration, or explicit instantiation
14825a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// definition.
14835a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  bool isExplicitInstantiationOrSpecialization() const {
14845a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    switch (getTemplateSpecializationKind()) {
14855a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitSpecialization:
14865a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDeclaration:
14875a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ExplicitInstantiationDefinition:
14885a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return true;
14895a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
14905a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_Undeclared:
14915a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    case TSK_ImplicitInstantiation:
14925a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall      return false;
14935a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    }
14945a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall    llvm_unreachable("bad template specialization kind");
14955a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
14965a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
1497cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
1498cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
1499cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
1500cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
15019cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief Get the point of instantiation (if any), or null if none.
15029cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation getPointOfInstantiation() const {
15039cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    return PointOfInstantiation;
15049cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
15059cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
15069cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  void setPointOfInstantiation(SourceLocation Loc) {
15079cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    assert(Loc.isValid() && "point of instantiation must be valid!");
15089cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    PointOfInstantiation = Loc;
15099cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
15109cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
151137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
151237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
151337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
151437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
15151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::PointerUnion<ClassTemplateDecl *,
151637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
151737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
151837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
1519d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
1520d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
1521e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor      return llvm::PointerUnion<ClassTemplateDecl *,
1522e0329acf5c9437e2086a2fb2bf7a95ae2ac96505Douglas Gregor                                ClassTemplatePartialSpecializationDecl *>();
15231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
152537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
152637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
15271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1528f8c12146fa2153a6d97b7c92d27d2ece0cd26e79Dmitri Gribenko    return SpecializedTemplate.get<ClassTemplateDecl*>();
152937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
15301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
153194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Retrieve the class template or class template partial
153294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// specialization which was specialized by this.
153394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  llvm::PointerUnion<ClassTemplateDecl *,
153494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis                     ClassTemplatePartialSpecializationDecl *>
153594d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  getSpecializedTemplateOrPartial() const {
153694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    if (SpecializedPartialSpecialization *PartialSpec
153794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
153894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis      return PartialSpec->PartialSpecialization;
153994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1540f8c12146fa2153a6d97b7c92d27d2ece0cd26e79Dmitri Gribenko    return SpecializedTemplate.get<ClassTemplateDecl*>();
154194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
154294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
154337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
154437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
154537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
154637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
154737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
154837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
154937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
155037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
155137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
155237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
155337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
155437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
15551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
155637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
155737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
15581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
155937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
156037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
15611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
156237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
156337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
156437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
156537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
1566d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith                          const TemplateArgumentList *TemplateArgs) {
156794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
156894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Already set to a class template partial specialization!");
15691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SpecializedPartialSpecialization *PS
157037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
157137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
157237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
157337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
157437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
15751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
157694d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// \brief Note that this class template specialization is an instantiation
157794d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  /// of the given class template.
157894d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
157994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
158094d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis           "Previously set to a class template partial specialization!");
158194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    SpecializedTemplate = TemplDecl;
158294d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  }
158394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1584fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
1585fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
15863cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  void setTypeAsWritten(TypeSourceInfo *T) {
1587db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1588db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1589c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TypeAsWritten = T;
15903cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  }
15913cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Gets the type of this specialization as it was written by
15923cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// the user, if it was so written.
15933cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  TypeSourceInfo *getTypeAsWritten() const {
1594c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
1595c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1596c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1597c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the extern keyword, if present.
1598c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getExternLoc() const {
1599c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
1600c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1601c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the extern keyword.
1602c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setExternLoc(SourceLocation Loc) {
1603db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1604db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1605c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->ExternLoc = Loc;
1606c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1607c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara
1608c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Sets the location of the template keyword.
1609c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  void setTemplateKeywordLoc(SourceLocation Loc) {
1610db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek    if (!ExplicitInfo)
1611db1423008b6185fc570558cff77d92f94e55b386Ted Kremenek      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1612c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    ExplicitInfo->TemplateKeywordLoc = Loc;
1613c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  }
1614c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  /// \brief Gets the location of the template keyword, if present.
1615c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara  SourceLocation getTemplateKeywordLoc() const {
1616c98971d5c994caed9452aeadd0122c855e0f4de1Abramo Bagnara    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
1617fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
1618fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
1619aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
16204a85a73466bfb541cd9c7b57a99292a0b6900b9bAbramo Bagnara
1621c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1622910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
1623c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1624c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
16251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
16261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
1627828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
16280ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
16293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
1630828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
16313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
16323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
163380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
163480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
16359a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt    return K >= firstClassTemplateSpecialization &&
16369a55591af3e5506b95a9718e15380129fbfc5ebcSean Hunt           K <= lastClassTemplateSpecialization;
16373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
16383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1639586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclReader;
1640586c7156d51039290f100c80d2d8bd263c99addcArgyrios Kyrtzidis  friend class ASTDeclWriter;
1641c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1642c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
16431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplatePartialSpecializationDecl
16441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public ClassTemplateSpecializationDecl {
164599ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
164699ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
16471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The list of template parameters
1648c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1649c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1650833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief The source info for the template arguments as written.
16513cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// FIXME: redundant with TypeAsWritten?
1652c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *ArgsAsWritten;
1653833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1654ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The class template partial specialization from which this
1655ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// class template partial specialization was instantiated.
1656ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1657ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// The boolean value will be true to indicate that this class template
1658ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// partial specialization was specialized at this level.
1659ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
1660ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      InstantiatedFromMember;
1661ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
166213c8577201e4fc0ddac5f09d05fd1778832137d1Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1663ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         DeclContext *DC,
1664ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         SourceLocation StartLoc,
1665ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara                                         SourceLocation IdLoc,
1666c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1667c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
1668910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                         const TemplateArgument *Args,
1669910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                         unsigned NumArgs,
1670c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella                               const ASTTemplateArgumentListInfo *ArgsAsWritten,
167137fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith                               ClassTemplatePartialSpecializationDecl *PrevDecl);
1672ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
167394d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl()
167494d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis    : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
167537fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith      TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { }
1676c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1677c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1678c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
1679ff91d240d431afbec18e25909caaf5c17f26e643Nico Weber  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1680ba877adeb49ed6dc17f27fa3a3bcd0cca713fd68Abramo Bagnara         SourceLocation StartLoc, SourceLocation IdLoc,
1681c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1682c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
1683910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         const TemplateArgument *Args,
1684910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor         unsigned NumArgs,
1685d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall         const TemplateArgumentListInfo &ArgInfos,
16863cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall         QualType CanonInjectedType,
168737fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith         ClassTemplatePartialSpecializationDecl *PrevDecl);
1688c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
168994d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis  static ClassTemplatePartialSpecializationDecl *
16901e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  CreateDeserialized(ASTContext &C, unsigned ID);
169194d228d3454a3f6436526d15b2ad7fc90246fe54Argyrios Kyrtzidis
1692ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
1693cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis    return cast<ClassTemplatePartialSpecializationDecl>(
1694ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor                   ClassTemplateSpecializationDecl::getMostRecentDecl());
1695cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  }
1696cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1697c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1698c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1699c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1700c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1701c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1702833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// Get the template arguments as written.
1703c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
1704833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return ArgsAsWritten;
1705833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
1706833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
1707ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Retrieve the member class template partial specialization from
1708ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// which this particular class template partial specialization was
1709ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// instantiated.
1710ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1711ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1712ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1713ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct Outer {
1714ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1715ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*> { }; // #1
1716ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1717ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1718ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// Outer<float>::Inner<int*> ii;
1719ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1720ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1721ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
1722ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// end up instantiating the partial specialization
1723ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
1724ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// template partial specialization \c Outer<T>::Inner<U*>. Given
1725ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<float>::Inner<U*>, this function would return
1726ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c Outer<T>::Inner<U*>.
1727ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
1728ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1729ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1730ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getPointer();
1731ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1732ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1733ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setInstantiatedFromMember(
1734ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
1735ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1736ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1737ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    First->InstantiatedFromMember.setPointer(PartialSpec);
1738ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1739ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1740ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Determines whether this class template partial specialization
1741ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template was a specialization of a member partial specialization.
1742ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1743ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// In the following example, the member template partial specialization
1744ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \c X<int>::Inner<T*> is a member specialization.
1745ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1746ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \code
1747ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<typename T>
1748ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X {
1749ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner;
1750ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///   template<typename U> struct Inner<U*>;
1751ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// };
1752ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  ///
1753ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// template<> template<typename T>
1754ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// struct X<int>::Inner<T*> { /* ... */ };
1755ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \endcode
1756ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  bool isMemberSpecialization() {
1757ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1758ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1759ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.getInt();
1760ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
1761ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1762ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  /// \brief Note that this member template is a specialization.
1763ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  void setMemberSpecialization() {
1764ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    ClassTemplatePartialSpecializationDecl *First
1765ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor      = cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
1766ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    assert(First->InstantiatedFromMember.getPointer() &&
1767ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor           "Only member templates can be member template specializations");
1768ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor    return First->InstantiatedFromMember.setInt(true);
1769ed9c0f90b7e0811c209b95e39fe07c211c531285Douglas Gregor  }
177031f17ecbef57b5679c017c375db330546b7b5145John McCall
177131f17ecbef57b5679c017c375db330546b7b5145John McCall  /// Retrieves the injected specialization type for this partial
177231f17ecbef57b5679c017c375db330546b7b5145John McCall  /// specialization.  This is not the same as the type-decl-type for
177331f17ecbef57b5679c017c375db330546b7b5145John McCall  /// this partial specialization, which is an InjectedClassNameType.
177431f17ecbef57b5679c017c375db330546b7b5145John McCall  QualType getInjectedSpecializationType() const {
177531f17ecbef57b5679c017c375db330546b7b5145John McCall    assert(getTypeForDecl() && "partial specialization has no type set!");
177631f17ecbef57b5679c017c375db330546b7b5145John McCall    return cast<InjectedClassNameType>(getTypeForDecl())
177731f17ecbef57b5679c017c375db330546b7b5145John McCall             ->getInjectedSpecializationType();
177831f17ecbef57b5679c017c375db330546b7b5145John McCall  }
1779ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1780c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1781c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
178280cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
178380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) {
178480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall    return K == ClassTemplatePartialSpecialization;
1785c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1786c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
17878fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclReader;
17888fed4b4bc93cce4d15bdb79f9e30cc25a93c8143Argyrios Kyrtzidis  friend class ASTDeclWriter;
17893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
17903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
17913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
17927c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass ClassTemplateDecl : public RedeclarableTemplateDecl {
17930054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  static void DeallocateCommon(void *Ptr);
1794ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
17953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
17965953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
17975953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
17989eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  struct Common : CommonBase {
1799c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    Common() : LazySpecializations() { }
1800ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
18015953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
18025953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
1803d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
18047da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1805c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1806c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
1807d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth    llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
1808c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1809c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
18107da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
18117da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1812ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1813c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// \brief If non-null, points to an array of specializations (including
18146982bf4d77bc57a85ee173b631729fce673f16efRichard Smith    /// partial specializations) known only by their external declaration IDs.
1815c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    ///
1816c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// The first value in the array is the number of of specializations/
1817c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    /// partial specializations that follow.
1818c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor    uint32_t *LazySpecializations;
18195953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
18205953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1821c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  /// \brief Load any lazily-loaded specializations from the external source.
1822e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  void LoadLazySpecializations() const;
1823ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1824cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of specializations of this class template.
1825e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
1826e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  getSpecializations() const;
1827cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1828cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Retrieve the set of partial specializations of this class
1829cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// template.
1830d964d6380945e0505b623050fe6a3f428008fc2aChandler Carruth  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
1831c8e5cf8f725e111965debb7130ef7466c0c73884Douglas Gregor  getPartialSpecializations();
1832cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
18333e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
18348731ca76acf81826df7048bffd0c44c7c0f96c7fArgyrios Kyrtzidis                    TemplateParameterList *Params, NamedDecl *Decl)
18359eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
18369eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18379a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor  ClassTemplateDecl(EmptyShell Empty)
18389a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor    : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
18399a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor                               DeclarationName(), 0, 0) { }
18409a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
1841b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  CommonBase *newCommon(ASTContext &C) const;
18429eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1843e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  Common *getCommonPtr() const {
18449eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
18459eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18463e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
18473e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
1848d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Get the underlying class declarations of the template.
18493e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
18503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
18513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
18523e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1853d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Returns whether this template declaration defines the primary
185413fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  /// class pattern.
185513fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  bool isThisDeclarationADefinition() const {
185613fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall    return getTemplatedDecl()->isThisDeclarationADefinition();
185713fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall  }
185813fda8afe2ddd06c12bfb93a054e6b0d6d0d99f1John McCall
1859d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Create a class template node.
18603e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
18613e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
18623e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
18633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
18645953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
18655953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
18663e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1867d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Create an empty class template node.
18681e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
18699a299e0575ce235f491014627c7267e2d2cd73deDouglas Gregor
1870cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the specialization with the provided arguments if it exists,
1871cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// otherwise return the insertion point.
1872cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplateSpecializationDecl *
1873cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1874cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                     void *&InsertPos);
1875cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1876cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified specialization knowing that it is not already
1877cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// in. InsertPos must be obtained from findSpecialization.
1878bef1a7b9c175d37e4a727e6ce68bd05232fa6970Argyrios Kyrtzidis  void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
18793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
18809eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getCanonicalDecl() {
18817c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<ClassTemplateDecl>(
18827c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
18839eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18849eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  const ClassTemplateDecl *getCanonicalDecl() const {
18857c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<ClassTemplateDecl>(
18867c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
18879eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18889eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18899eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
18909eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
1891ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  ClassTemplateDecl *getPreviousDecl() {
18927c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<ClassTemplateDecl>(
1893ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor             RedeclarableTemplateDecl::getPreviousDecl());
18949eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
18959eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
18969eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// \brief Retrieve the previous declaration of this class template, or
18979eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  /// NULL if no such declaration exists.
1898ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  const ClassTemplateDecl *getPreviousDecl() const {
18997c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<ClassTemplateDecl>(
1900ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor             RedeclarableTemplateDecl::getPreviousDecl());
19019eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
19029eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
19039eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
19047c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<ClassTemplateDecl>(
19057c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
19069eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne  }
19079eabebafc165a67812eacc184806e7bf34c5f0a5Peter Collingbourne
1908cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Return the partial specialization with the provided arguments if it
1909cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// exists, otherwise return the insertion point.
1910cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1911cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1912cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                            void *&InsertPos);
1913cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1914cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Insert the specified partial specialization knowing that it is not
1915cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// already in. InsertPos must be obtained from findPartialSpecialization.
1916cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
1917bef1a7b9c175d37e4a727e6ce68bd05232fa6970Argyrios Kyrtzidis                                void *InsertPos);
1918cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis
1919dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  /// \brief Retrieve the partial specializations as an ordered list.
1920dc60c1eb4acbde6edcec9760de92f9098593d915Douglas Gregor  void getPartialSpecializations(
1921686775deca8b8685eb90801495880e3abdd844c2Chris Lattner          SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
1922ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1923b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1924b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1925b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1926cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param T a dependent type that names a specialization of this class
1927b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1928b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1929b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1930b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1931b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
1932ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1933cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \brief Find a class template partial specialization which was instantiated
1934cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization.
1935cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1936cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \param D a member class template partial specialization.
1937cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ///
1938cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// \returns the class template partial specialization which was instantiated
1939cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// from the given member partial specialization, or NULL if no such partial
1940cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  /// specialization exists.
1941cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  ClassTemplatePartialSpecializationDecl *
1942cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis  findPartialSpecInstantiatedFromMember(
1943cc0b1bc979b650a8a8b34b2032a074fd7724a90dArgyrios Kyrtzidis                                     ClassTemplatePartialSpecializationDecl *D);
19441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19453cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// \brief Retrieve the template specialization type of the
19463cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  /// injected-class-name for this class template.
19477da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
19487da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
19497da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
19507da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
19517da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
19527da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
19537da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
19547da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
19557da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
19567da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
19577da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
19587da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
195924bae92f08ae098cc50a602d8cf1273b423e14daDouglas Gregor  QualType getInjectedClassNameSpecialization();
19607da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
19619f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
19629f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
1963e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_begin() const {
19649f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), false);
19659f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19669f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
1967e252a89fc1560ca4cda9a95e4ae05e2dc03ee78cDmitri Gribenko  spec_iterator spec_end() const {
19689f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getSpecializations(), true);
19699f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19709f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19719f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
19729f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne          partial_spec_iterator;
19739f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19749f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  partial_spec_iterator partial_spec_begin() {
19759f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getPartialSpecializations(), false);
19769f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19779f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19789f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  partial_spec_iterator partial_spec_end() {
19799f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne    return makeSpecIterator(getPartialSpecializations(), true);
19809f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne  }
19819f339ba5b00256588d0d78786fff6d48ef073015Peter Collingbourne
19823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
198380cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
198480cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == ClassTemplate; }
19855953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
1986d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
19873397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
19883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
19893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1990d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of a friend template.
1991dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///
1992d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// For example:
1993d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
1994d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// template \<typename T> class A {
1995dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   friend class MyVector<T>; // not a friend template
1996d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<typename U> friend class B; // not a friend template
1997d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///   template \<typename U> friend class Foo<T>::Nested; // friend template
1998c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// };
1999d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
2000d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
2001d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \note This class is not currently in use.  All of the above
2002c6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0Craig Silverstein/// will yield a FriendDecl, not a FriendTemplateDecl.
2003dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallclass FriendTemplateDecl : public Decl {
200499ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
2005dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
200632f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
2007dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2008dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallprivate:
2009dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The number of template parameters;  always non-zero.
2010dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned NumParams;
2011dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2012dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The parameter list.
2013dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList **Params;
2014dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2015dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The declaration that's a friend of this class.
2016dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendUnion Friend;
2017dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2018dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Location of the 'friend' specifier.
2019dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation FriendLoc;
2020dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2021dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2022dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
2023ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                     unsigned NParams,
2024dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     TemplateParameterList **Params,
2025dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     FriendUnion Friend,
2026dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     SourceLocation FriendLoc)
2027dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    : Decl(Decl::FriendTemplate, DC, Loc),
2028dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      NumParams(NParams),
2029dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Params(Params),
2030dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Friend(Friend),
2031dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      FriendLoc(FriendLoc)
2032dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  {}
2033dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2034554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  FriendTemplateDecl(EmptyShell Empty)
2035554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis    : Decl(Decl::FriendTemplate, Empty),
2036554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis      NumParams(0),
2037554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis      Params(0)
2038554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis  {}
2039554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2040dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
2041dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static FriendTemplateDecl *Create(ASTContext &Context,
2042dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    DeclContext *DC, SourceLocation Loc,
2043ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                                    unsigned NParams,
2044dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    TemplateParameterList **Params,
2045dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    FriendUnion Friend,
2046dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    SourceLocation FriendLoc);
2047dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
20481e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2049554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2050dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated type (or
2051dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a dependent member type of a templated type), return that
2052dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// type;  otherwise return null.
205332f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall  TypeSourceInfo *getFriendType() const {
205432f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall    return Friend.dyn_cast<TypeSourceInfo*>();
2055dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2056dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2057dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated function (or
2058dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a member function of a templated type), return that type;
2059dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// otherwise return null.
2060dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  NamedDecl *getFriendDecl() const {
2061dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Friend.dyn_cast<NamedDecl*>();
2062dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2063dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2064d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett  /// \brief Retrieves the location of the 'friend' keyword.
2065dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation getFriendLoc() const {
2066dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return FriendLoc;
2067dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2068dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2069dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList *getTemplateParameterList(unsigned i) const {
2070dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    assert(i <= NumParams);
2071dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Params[i];
2072dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2073dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2074dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned getNumTemplateParameters() const {
2075dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return NumParams;
2076dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
2077dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2078dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Implement isa/cast/dyncast/etc.
207980cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
208080cd64a8450d8e2c079dc134d9711cd45ba89d63John McCall  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2081554e6aa2da082575514607c3639c246c04b3232aArgyrios Kyrtzidis
2082d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl  friend class ASTDeclReader;
2083dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall};
2084dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
2085d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of an alias template.
20863e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith///
2087d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// For example:
2088d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
2089d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
2090d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
20917c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregorclass TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
20923e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static void DeallocateCommon(void *Ptr);
20933e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20943e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithprotected:
20953e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  typedef CommonBase Common;
20963e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
20973e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
20983e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                        TemplateParameterList *Params, NamedDecl *Decl)
20993e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
21003e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2101b76d9718caea48b9333979b3da6f3a80110840cbDmitri Gribenko  CommonBase *newCommon(ASTContext &C) const;
21023e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21033e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  Common *getCommonPtr() {
21043e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
21053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21063e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21073e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smithpublic:
21083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// Get the underlying function declaration of the template.
21093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasDecl *getTemplatedDecl() const {
21103e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return static_cast<TypeAliasDecl*>(TemplatedDecl);
21113e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21133e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21143e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl *getCanonicalDecl() {
21157c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<TypeAliasTemplateDecl>(
21167c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
21173e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21183e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  const TypeAliasTemplateDecl *getCanonicalDecl() const {
21197c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast<TypeAliasTemplateDecl>(
21207c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getCanonicalDecl());
21213e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21223e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21233e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Retrieve the previous declaration of this function template, or
21243e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// NULL if no such declaration exists.
2125ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  TypeAliasTemplateDecl *getPreviousDecl() {
21267c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<TypeAliasTemplateDecl>(
2127ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor             RedeclarableTemplateDecl::getPreviousDecl());
21283e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21293e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21303e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Retrieve the previous declaration of this function template, or
21313e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// NULL if no such declaration exists.
2132ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor  const TypeAliasTemplateDecl *getPreviousDecl() const {
21337c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<TypeAliasTemplateDecl>(
2134ef96ee0be5f100789f451641542a69cd719144d2Douglas Gregor             RedeclarableTemplateDecl::getPreviousDecl());
21353e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21363e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21373e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
21387c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor    return cast_or_null<TypeAliasTemplateDecl>(
21397c99bb5c4901c39460818ff8c00840218c48251fDouglas Gregor             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
21403e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
21413e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2142ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
21433e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Create a function template node.
21443e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
21453e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       SourceLocation L,
21463e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       DeclarationName Name,
21473e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       TemplateParameterList *Params,
21483e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                       NamedDecl *Decl);
21493e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21503e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  /// \brief Create an empty alias template node.
21511e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
21523e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21533e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  // Implement isa/cast/dyncast support
21543e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
21553e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
21563e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
21573e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  friend class ASTDeclReader;
21583e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  friend class ASTDeclWriter;
21593e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith};
21603e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
2161d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \brief Declaration of a function specialization at template class scope.
2162d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
2163af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// This is a non standard extension needed to support MSVC.
2164d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett///
2165af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// For example:
2166d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \code
2167af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// template <class T>
2168af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// class A {
2169af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet///    template <class U> void foo(U a) { }
2170af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet///    template<> void foo(int a) { }
2171af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// }
2172d5e26b8933a377893c8043ff6a23aaf6b601d18fJames Dennett/// \endcode
2173af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet///
2174af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// "template<> foo(int a)" will be saved in Specialization as a normal
2175af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// CXXMethodDecl. Then during an instantiation of class A, it will be
2176af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet/// transformed into an actual function specialization.
2177af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichetclass ClassScopeFunctionSpecializationDecl : public Decl {
217899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie  virtual void anchor();
217999ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
2180af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
21816b02009359a462ffe633696a4441313b462e6566Nico Weber                                       CXXMethodDecl *FD, bool Args,
21826b02009359a462ffe633696a4441313b462e6566Nico Weber                                       TemplateArgumentListInfo TemplArgs)
2183af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
21846b02009359a462ffe633696a4441313b462e6566Nico Weber      Specialization(FD), HasExplicitTemplateArgs(Args),
21856b02009359a462ffe633696a4441313b462e6566Nico Weber      TemplateArgs(TemplArgs) {}
2186af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2187af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
2188af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
2189af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2190af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  CXXMethodDecl *Specialization;
21916b02009359a462ffe633696a4441313b462e6566Nico Weber  bool HasExplicitTemplateArgs;
21926b02009359a462ffe633696a4441313b462e6566Nico Weber  TemplateArgumentListInfo TemplateArgs;
2193af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2194af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichetpublic:
2195af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  CXXMethodDecl *getSpecialization() const { return Specialization; }
21966b02009359a462ffe633696a4441313b462e6566Nico Weber  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
21976b02009359a462ffe633696a4441313b462e6566Nico Weber  const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
2198af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2199af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
2200af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet                                                      DeclContext *DC,
2201af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet                                                      SourceLocation Loc,
22026b02009359a462ffe633696a4441313b462e6566Nico Weber                                                      CXXMethodDecl *FD,
22036b02009359a462ffe633696a4441313b462e6566Nico Weber                                                   bool HasExplicitTemplateArgs,
22046b02009359a462ffe633696a4441313b462e6566Nico Weber                                        TemplateArgumentListInfo TemplateArgs) {
22056b02009359a462ffe633696a4441313b462e6566Nico Weber    return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD,
22066b02009359a462ffe633696a4441313b462e6566Nico Weber                                                        HasExplicitTemplateArgs,
22076b02009359a462ffe633696a4441313b462e6566Nico Weber                                                        TemplateArgs);
2208af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  }
2209af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
22101e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  static ClassScopeFunctionSpecializationDecl *
22111e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor  CreateDeserialized(ASTContext &Context, unsigned ID);
22121e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor
2213af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  // Implement isa/cast/dyncast/etc.
2214af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2215af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  static bool classofKind(Kind K) {
2216af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    return K == Decl::ClassScopeFunctionSpecialization;
2217af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  }
2218af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2219af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  friend class ASTDeclReader;
2220af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  friend class ASTDeclWriter;
2221af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet};
2222af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
2223e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
22241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
2225e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
2226e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
2227ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// \brief Represents a variable template specialization, which refers to
2228ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// a variable template with a given set of template arguments.
2229ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo///
2230ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// Variable template specializations represent both explicit
2231ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// specializations of variable templates, as in the example below, and
2232ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// implicit instantiations of variable templates.
2233ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo///
2234ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// \code
2235ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2236ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo///
2237ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// template<>
2238ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// constexpr float pi<float>; // variable template specialization pi<float>
2239ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// \endcode
2240ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplateSpecializationDecl : public VarDecl,
2241ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                      public llvm::FoldingSetNode {
2242ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2243ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Structure that stores information about a variable template
2244ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization that was instantiated from a variable template partial
2245ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization.
2246ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  struct SpecializedPartialSpecialization {
2247ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The variable template partial specialization from which this
2248ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// variable template specialization was instantiated.
2249ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *PartialSpecialization;
2250ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2251ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The template argument list deduced for the variable template
2252ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// partial specialization itself.
2253d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith    const TemplateArgumentList *TemplateArgs;
2254ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
2255ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2256ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The template that this specialization specializes.
2257ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2258ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SpecializedTemplate;
2259ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2260ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Further info for explicit template specialization/instantiation.
2261ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  struct ExplicitSpecializationInfo {
2262ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The type-as-written.
2263ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    TypeSourceInfo *TypeAsWritten;
2264ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The location of the extern keyword.
2265ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SourceLocation ExternLoc;
2266ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The location of the template keyword.
2267ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SourceLocation TemplateKeywordLoc;
2268ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2269ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitSpecializationInfo()
2270ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
2271ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
2272ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2273ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Further info for explicit template specialization/instantiation.
2274ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Does not apply to implicit specializations.
2275ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ExplicitSpecializationInfo *ExplicitInfo;
2276ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2277ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The template arguments used to describe this specialization.
2278d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith  const TemplateArgumentList *TemplateArgs;
2279ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateArgumentListInfo TemplateArgsInfo;
2280ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2281ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The point where this template was instantiated (if any).
2282ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation PointOfInstantiation;
2283ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2284ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The kind of specialization this declaration refers to.
2285ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Really a value of type TemplateSpecializationKind.
2286ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  unsigned SpecializationKind : 3;
2287ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2288ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoprotected:
2289ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC,
2290ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                SourceLocation StartLoc, SourceLocation IdLoc,
2291ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                VarTemplateDecl *SpecializedTemplate,
2292ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                QualType T, TypeSourceInfo *TInfo,
2293ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                StorageClass S, const TemplateArgument *Args,
2294ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                unsigned NumArgs);
2295ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2296ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  explicit VarTemplateSpecializationDecl(Kind DK);
2297ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2298ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufopublic:
2299ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateSpecializationDecl *
2300ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2301ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2302ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
2303ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         unsigned NumArgs);
2304ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
2305ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                                           unsigned ID);
2306ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2307ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  virtual void getNameForDiagnostic(raw_ostream &OS,
2308ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                    const PrintingPolicy &Policy,
2309ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                    bool Qualified) const;
2310ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2311ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateSpecializationDecl *getMostRecentDecl() {
2312ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarDecl *Recent = cast<VarDecl>(VarDecl::getMostRecentDecl());
2313ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplateSpecializationDecl>(Recent);
2314ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2315ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2316ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the template that this specialization specializes.
2317ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getSpecializedTemplate() const;
2318ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2319ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the template arguments of the variable template
2320ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization.
2321ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2322ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2323ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  // TODO: Always set this when creating the new specialization?
2324ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
2325ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2326ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const TemplateArgumentListInfo &getTemplateArgsInfo() const {
2327ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return TemplateArgsInfo;
2328ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2329ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2330ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Determine the kind of specialization that this
2331ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// declaration represents.
2332ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateSpecializationKind getSpecializationKind() const {
2333ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return static_cast<TemplateSpecializationKind>(SpecializationKind);
2334ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2335ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2336ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isExplicitSpecialization() const {
2337ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return getSpecializationKind() == TSK_ExplicitSpecialization;
2338ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2339ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2340ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief True if this declaration is an explicit specialization,
2341ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// explicit instantiation declaration, or explicit instantiation
2342ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// definition.
2343ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isExplicitInstantiationOrSpecialization() const {
2344ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    switch (getTemplateSpecializationKind()) {
2345ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ExplicitSpecialization:
2346ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ExplicitInstantiationDeclaration:
2347ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ExplicitInstantiationDefinition:
2348ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return true;
2349ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2350ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_Undeclared:
2351ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    case TSK_ImplicitInstantiation:
2352ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return false;
2353ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    }
2354ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    llvm_unreachable("bad template specialization kind");
2355ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2356ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2357ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setSpecializationKind(TemplateSpecializationKind TSK) {
2358ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializationKind = TSK;
2359ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2360ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2361ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Get the point of instantiation (if any), or null if none.
2362ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation getPointOfInstantiation() const {
2363ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return PointOfInstantiation;
2364ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2365ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2366ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setPointOfInstantiation(SourceLocation Loc) {
2367ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(Loc.isValid() && "point of instantiation must be valid!");
2368ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PointOfInstantiation = Loc;
2369ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2370ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2371ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief If this variable template specialization is an instantiation of
2372ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// a template (rather than an explicit specialization), return the
2373ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template or variable template partial specialization from which
2374ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// it was instantiated.
2375ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2376ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getInstantiatedFrom() const {
2377ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
2378ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
2379ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
2380ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return llvm::PointerUnion<VarTemplateDecl *,
2381ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                VarTemplatePartialSpecializationDecl *>();
2382ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2383ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (SpecializedPartialSpecialization *PartialSpec =
2384ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2385ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return PartialSpec->PartialSpecialization;
2386ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2387ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return SpecializedTemplate.get<VarTemplateDecl *>();
2388ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2389ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2390ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the variable template or variable template partial
2391ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization which was specialized by this.
2392ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2393ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getSpecializedTemplateOrPartial() const {
2394ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (SpecializedPartialSpecialization *PartialSpec =
2395ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2396ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return PartialSpec->PartialSpecialization;
2397ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2398ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return SpecializedTemplate.get<VarTemplateDecl *>();
2399ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2400ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2401ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the set of template arguments that should be used
2402ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// to instantiate the initializer of the variable template or variable
2403ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template partial specialization from which this variable template
2404ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization was instantiated.
2405ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2406ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \returns For a variable template specialization instantiated from the
2407ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// primary template, this function will return the same template arguments
2408ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// as getTemplateArgs(). For a variable template specialization instantiated
2409ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// from a variable template partial specialization, this function will the
2410ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// return deduced template arguments for the variable template partial
2411ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization itself.
2412ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const TemplateArgumentList &getTemplateInstantiationArgs() const {
2413ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (SpecializedPartialSpecialization *PartialSpec =
2414ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2415ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      return *PartialSpec->TemplateArgs;
2416ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2417ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return getTemplateArgs();
2418ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2419ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2420ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Note that this variable template specialization is actually an
2421ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiation of the given variable template partial specialization whose
2422ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template arguments have been deduced.
2423ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
2424d0629eb137d06bf6d46a430abdb7fa044909298bRichard Smith                          const TemplateArgumentList *TemplateArgs) {
2425ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2426ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           "Already set to a variable template partial specialization!");
2427ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializedPartialSpecialization *PS =
2428ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        new (getASTContext()) SpecializedPartialSpecialization();
2429ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PS->PartialSpecialization = PartialSpec;
2430ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PS->TemplateArgs = TemplateArgs;
2431ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializedTemplate = PS;
2432ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2433ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2434ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Note that this variable template specialization is an instantiation
2435ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// of the given variable template.
2436ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setInstantiationOf(VarTemplateDecl *TemplDecl) {
2437ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2438ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           "Previously set to a variable template partial specialization!");
2439ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    SpecializedTemplate = TemplDecl;
2440ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2441ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2442ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Sets the type of this specialization as it was written by
2443ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// the user.
2444ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setTypeAsWritten(TypeSourceInfo *T) {
2445ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (!ExplicitInfo)
2446ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2447ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitInfo->TypeAsWritten = T;
2448ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2449ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Gets the type of this specialization as it was written by
2450ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// the user, if it was so written.
2451ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TypeSourceInfo *getTypeAsWritten() const {
2452ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
2453ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2454ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2455ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Gets the location of the extern keyword, if present.
2456ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation getExternLoc() const {
2457ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2458ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2459ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Sets the location of the extern keyword.
2460ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setExternLoc(SourceLocation Loc) {
2461ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (!ExplicitInfo)
2462ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2463ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitInfo->ExternLoc = Loc;
2464ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2465ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2466ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Sets the location of the template keyword.
2467ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setTemplateKeywordLoc(SourceLocation Loc) {
2468ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    if (!ExplicitInfo)
2469ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2470ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ExplicitInfo->TemplateKeywordLoc = Loc;
2471ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2472ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Gets the location of the template keyword, if present.
2473ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  SourceLocation getTemplateKeywordLoc() const {
2474ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2475ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2476ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2477ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void Profile(llvm::FoldingSetNodeID &ID) const {
2478ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
2479ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2480ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2481ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static void Profile(llvm::FoldingSetNodeID &ID,
2482ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                      const TemplateArgument *TemplateArgs,
2483ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                      unsigned NumTemplateArgs, ASTContext &Context) {
2484ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ID.AddInteger(NumTemplateArgs);
2485ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
2486ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      TemplateArgs[Arg].Profile(ID, Context);
2487ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2488ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2489ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2490ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classofKind(Kind K) {
2491ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return K >= firstVarTemplateSpecialization &&
2492ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           K <= lastVarTemplateSpecialization;
2493ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2494ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2495ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclReader;
2496ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclWriter;
2497ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo};
2498ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2499ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplatePartialSpecializationDecl
2500ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    : public VarTemplateSpecializationDecl {
2501ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  virtual void anchor();
2502ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2503ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The list of template parameters
2504ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateParameterList *TemplateParams;
2505ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2506ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The source info for the template arguments as written.
2507ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// FIXME: redundant with TypeAsWritten?
2508c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *ArgsAsWritten;
2509ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2510ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief The variable template partial specialization from which this
2511ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template partial specialization was instantiated.
2512ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2513ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// The boolean value will be true to indicate that this variable template
2514ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// partial specialization was specialized at this level.
2515ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2516ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  InstantiatedFromMember;
2517ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2518ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl(
2519ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2520ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      SourceLocation IdLoc, TemplateParameterList *Params,
2521ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2522ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
252337fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith      const ASTTemplateArgumentListInfo *ArgInfos);
2524ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2525ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl()
2526ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization),
252737fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith        TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {}
2528ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2529ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufopublic:
2530ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplatePartialSpecializationDecl *
2531ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2532ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         SourceLocation IdLoc, TemplateParameterList *Params,
2533ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         VarTemplateDecl *SpecializedTemplate, QualType T,
2534ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
253537fd27dbb941d27f4bd7412e534e7e5089d6781bRichard Smith         unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
2536ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2537ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
2538ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                                                  unsigned ID);
2539ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2540ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2541ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplatePartialSpecializationDecl>(
2542ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        VarTemplateSpecializationDecl::getMostRecentDecl());
2543ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2544ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2545ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Get the list of template parameters
2546ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  TemplateParameterList *getTemplateParameters() const {
2547ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return TemplateParams;
2548ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2549ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2550ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// Get the template arguments as written.
2551c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2552ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return ArgsAsWritten;
2553ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2554ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2555ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the member variable template partial specialization from
2556ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// which this particular variable template partial specialization was
2557ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiated.
2558ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2559ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \code
2560ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template<typename T>
2561ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// struct Outer {
2562ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U Inner;
2563ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U* Inner<U*> = (U*)(0); // #1
2564ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// };
2565ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2566ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template int* Outer<float>::Inner<int*>;
2567ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \endcode
2568ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2569ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2570ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// end up instantiating the partial specialization
2571ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2572ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2573ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c Outer<float>::Inner<U*>, this function would return
2574ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c Outer<T>::Inner<U*>.
2575ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
2576ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2577ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        cast<VarTemplatePartialSpecializationDecl>(getFirstDeclaration());
2578ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return First->InstantiatedFromMember.getPointer();
2579ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2580ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2581ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void
2582ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2583ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2584ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        cast<VarTemplatePartialSpecializationDecl>(getFirstDeclaration());
2585ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    First->InstantiatedFromMember.setPointer(PartialSpec);
2586ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2587ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2588ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Determines whether this variable template partial specialization
2589ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// was a specialization of a member partial specialization.
2590ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2591ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// In the following example, the member template partial specialization
2592ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \c X<int>::Inner<T*> is a member specialization.
2593ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2594ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \code
2595ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template<typename T>
2596ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// struct X {
2597ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U Inner;
2598ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///   template<typename U> U* Inner<U*> = (U*)(0);
2599ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// };
2600ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2601ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template<> template<typename T>
2602ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2603ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \endcode
2604ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isMemberSpecialization() {
2605ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2606ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        cast<VarTemplatePartialSpecializationDecl>(getFirstDeclaration());
2607ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return First->InstantiatedFromMember.getInt();
2608ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2609ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2610ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Note that this member template is a specialization.
2611ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void setMemberSpecialization() {
2612ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    VarTemplatePartialSpecializationDecl *First =
2613ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        cast<VarTemplatePartialSpecializationDecl>(getFirstDeclaration());
2614ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    assert(First->InstantiatedFromMember.getPointer() &&
2615ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo           "Only member templates can be member template specializations");
2616ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return First->InstantiatedFromMember.setInt(true);
2617ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2618ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2619ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2620ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static bool classofKind(Kind K) {
2621ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return K == VarTemplatePartialSpecialization;
2622ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2623ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2624ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclReader;
2625ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  friend class ASTDeclWriter;
2626ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo};
2627ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2628ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo/// Declaration of a variable template.
2629ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoclass VarTemplateDecl : public RedeclarableTemplateDecl {
2630ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static void DeallocateCommon(void *Ptr);
2631ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2632ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufoprotected:
2633ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Data that is common to all of the declarations of a given
2634ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable template.
2635ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  struct Common : CommonBase {
2636ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    Common() : LazySpecializations() {}
2637ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2638ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The variable template specializations for this variable
2639ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// template, including explicit specializations and instantiations.
2640ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
2641ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2642ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief The variable template partial specializations for this variable
2643ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// template.
2644ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
2645ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    PartialSpecializations;
2646ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2647ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// \brief If non-null, points to an array of specializations (including
2648ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// partial specializations) known ownly by their external declaration IDs.
2649ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    ///
2650ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// The first value in the array is the number of of specializations/
2651ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    /// partial specializations that follow.
2652ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    uint32_t *LazySpecializations;
2653ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  };
2654ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2655ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Load any lazily-loaded specializations from the external source.
2656ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void LoadLazySpecializations() const;
2657ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2658ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the set of specializations of this variable template.
2659ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
2660ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getSpecializations() const;
2661ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2662ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the set of partial specializations of this class
2663ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// template.
2664ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
2665ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  getPartialSpecializations();
2666ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2667ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
2668ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                  TemplateParameterList *Params, NamedDecl *Decl)
2669ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {}
2670ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2671ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl(EmptyShell Empty)
2672ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(),
2673ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                 DeclarationName(), 0, 0) {}
2674ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2675ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  CommonBase *newCommon(ASTContext &C) const;
2676ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2677ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  Common *getCommonPtr() const {
2678ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2679ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2680ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2681ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufopublic:
2682ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Get the underlying variable declarations of the template.
2683ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarDecl *getTemplatedDecl() const {
2684ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return static_cast<VarDecl *>(TemplatedDecl);
2685ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2686ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2687ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Returns whether this template declaration defines the primary
2688ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// variable pattern.
2689ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  bool isThisDeclarationADefinition() const {
2690ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return getTemplatedDecl()->isThisDeclarationADefinition();
2691ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2692ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2693439d665f4d1066ee5ebd8dd0938d85be83d490c4Larisse Voufo  VarTemplateDecl *getDefinition();
2694439d665f4d1066ee5ebd8dd0938d85be83d490c4Larisse Voufo
2695ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Create a variable template node.
2696ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
2697ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                 SourceLocation L, DeclarationName Name,
2698ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                 TemplateParameterList *Params, NamedDecl *Decl,
2699ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                 VarTemplateDecl *PrevDecl);
2700ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2701ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Create an empty variable template node.
2702ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2703ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2704ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Return the specialization with the provided arguments if it exists,
2705ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// otherwise return the insertion point.
2706ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateSpecializationDecl *
2707ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
2708ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                     void *&InsertPos);
2709ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2710ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Insert the specified specialization knowing that it is not already
2711ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// in. InsertPos must be obtained from findSpecialization.
2712ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
2713ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2714ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getCanonicalDecl() {
2715ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
2716ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2717ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const VarTemplateDecl *getCanonicalDecl() const {
2718ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
2719ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2720ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2721ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the previous declaration of this variable template, or
2722ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// NULL if no such declaration exists.
2723ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getPreviousDecl() {
2724ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast_or_null<VarTemplateDecl>(
2725ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        RedeclarableTemplateDecl::getPreviousDecl());
2726ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2727ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2728ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the previous declaration of this variable template, or
2729ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// NULL if no such declaration exists.
2730ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  const VarTemplateDecl *getPreviousDecl() const {
2731ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast_or_null<VarTemplateDecl>(
2732ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        RedeclarableTemplateDecl::getPreviousDecl());
2733ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2734ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2735ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplateDecl *getInstantiatedFromMemberTemplate() {
2736ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return cast_or_null<VarTemplateDecl>(
2737ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
2738ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2739ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2740ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Return the partial specialization with the provided arguments if it
2741ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// exists, otherwise return the insertion point.
2742ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *
2743ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
2744ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                            void *&InsertPos);
2745ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2746ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Insert the specified partial specialization knowing that it is not
2747ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// already in. InsertPos must be obtained from findPartialSpecialization.
2748ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
2749ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo                                void *InsertPos);
2750ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2751ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Retrieve the partial specializations as an ordered list.
2752ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  void getPartialSpecializations(
2753ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
2754ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2755ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \brief Find a variable template partial specialization which was
2756ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiated
2757ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// from the given member partial specialization.
2758ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2759ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \param D a member variable template partial specialization.
2760ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  ///
2761ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// \returns the variable template partial specialization which was
2762ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// instantiated
2763ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// from the given member partial specialization, or NULL if no such partial
2764ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  /// specialization exists.
2765ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
2766ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      VarTemplatePartialSpecializationDecl *D);
2767ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2768ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
2769ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2770ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  spec_iterator spec_begin() const {
2771ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getSpecializations(), false);
2772ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2773ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2774ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  spec_iterator spec_end() const {
2775ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getSpecializations(), true);
2776ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2777ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2778ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  typedef SpecIterator<VarTemplatePartialSpecializationDecl>
2779ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  partial_spec_iterator;
2780ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2781ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  partial_spec_iterator partial_spec_begin() {
2782ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getPartialSpecializations(), false);
2783ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  }
2784ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2785ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo  partial_spec_iterator partial_spec_end() {
2786ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo    return makeSpecIterator(getPartialSpecializations(), 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