1193326Sed//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9239462Sdim///
10239462Sdim/// \file
11239462Sdim/// \brief Defines the C++ template declaration subclasses.
12239462Sdim///
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15193326Sed#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
16193326Sed#define LLVM_CLANG_AST_DECLTEMPLATE_H
17193326Sed
18193326Sed#include "clang/AST/DeclCXX.h"
19234353Sdim#include "clang/AST/Redeclarable.h"
20198893Srdivacky#include "clang/AST/TemplateBase.h"
21194179Sed#include "llvm/ADT/PointerUnion.h"
22234353Sdim#include "llvm/Support/Compiler.h"
23194613Sed#include <limits>
24193326Sed
25193326Sednamespace clang {
26193326Sed
27193326Sedclass TemplateParameterList;
28193326Sedclass TemplateDecl;
29212904Sdimclass RedeclarableTemplateDecl;
30193326Sedclass FunctionTemplateDecl;
31193326Sedclass ClassTemplateDecl;
32193326Sedclass ClassTemplatePartialSpecializationDecl;
33193326Sedclass TemplateTypeParmDecl;
34193326Sedclass NonTypeTemplateParmDecl;
35193326Sedclass TemplateTemplateParmDecl;
36223017Sdimclass TypeAliasTemplateDecl;
37263508Sdimclass VarTemplateDecl;
38263508Sdimclass VarTemplatePartialSpecializationDecl;
39193326Sed
40194179Sed/// \brief Stores a template parameter of any kind.
41194179Sedtypedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
42194179Sed                            TemplateTemplateParmDecl*> TemplateParameter;
43194179Sed
44239462Sdim/// \brief Stores a list of template parameters for a TemplateDecl and its
45239462Sdim/// derived classes.
46193326Sedclass TemplateParameterList {
47193326Sed  /// The location of the 'template' keyword.
48193326Sed  SourceLocation TemplateLoc;
49193326Sed
50193326Sed  /// The locations of the '<' and '>' angle brackets.
51193326Sed  SourceLocation LAngleLoc, RAngleLoc;
52193326Sed
53193326Sed  /// The number of template parameters in this template
54193326Sed  /// parameter list.
55243830Sdim  unsigned NumParams : 31;
56193326Sed
57243830Sdim  /// Whether this template parameter list contains an unexpanded parameter
58243830Sdim  /// pack.
59243830Sdim  unsigned ContainsUnexpandedParameterPack : 1;
60243830Sdim
61219077Sdimprotected:
62193326Sed  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
63198092Srdivacky                        NamedDecl **Params, unsigned NumParams,
64193326Sed                        SourceLocation RAngleLoc);
65193326Sed
66193326Sedpublic:
67218893Sdim  static TemplateParameterList *Create(const ASTContext &C,
68193326Sed                                       SourceLocation TemplateLoc,
69193326Sed                                       SourceLocation LAngleLoc,
70198092Srdivacky                                       NamedDecl **Params,
71193326Sed                                       unsigned NumParams,
72193326Sed                                       SourceLocation RAngleLoc);
73193326Sed
74239462Sdim  /// \brief Iterates through the template parameters in this list.
75198092Srdivacky  typedef NamedDecl** iterator;
76193326Sed
77239462Sdim  /// \brief Iterates through the template parameters in this list.
78198092Srdivacky  typedef NamedDecl* const* const_iterator;
79193326Sed
80198092Srdivacky  iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
81193326Sed  const_iterator begin() const {
82198092Srdivacky    return reinterpret_cast<NamedDecl * const *>(this + 1);
83193326Sed  }
84193326Sed  iterator end() { return begin() + NumParams; }
85193326Sed  const_iterator end() const { return begin() + NumParams; }
86193326Sed
87193326Sed  unsigned size() const { return NumParams; }
88193326Sed
89249423Sdim  llvm::ArrayRef<NamedDecl*> asArray() {
90249423Sdim    return llvm::ArrayRef<NamedDecl*>(begin(), size());
91249423Sdim  }
92249423Sdim  llvm::ArrayRef<const NamedDecl*> asArray() const {
93249423Sdim    return llvm::ArrayRef<const NamedDecl*>(begin(), size());
94249423Sdim  }
95249423Sdim
96198092Srdivacky  NamedDecl* getParam(unsigned Idx) {
97194179Sed    assert(Idx < size() && "Template parameter index out-of-range");
98194179Sed    return begin()[Idx];
99194179Sed  }
100194179Sed
101198092Srdivacky  const NamedDecl* getParam(unsigned Idx) const {
102193326Sed    assert(Idx < size() && "Template parameter index out-of-range");
103193326Sed    return begin()[Idx];
104193326Sed  }
105193326Sed
106218893Sdim  /// \brief Returns the minimum number of arguments needed to form a
107239462Sdim  /// template specialization.
108239462Sdim  ///
109239462Sdim  /// This may be fewer than the number of template parameters, if some of
110239462Sdim  /// the parameters have default arguments or if there is a parameter pack.
111193326Sed  unsigned getMinRequiredArguments() const;
112193326Sed
113198893Srdivacky  /// \brief Get the depth of this template parameter list in the set of
114198893Srdivacky  /// template parameter lists.
115198893Srdivacky  ///
116198893Srdivacky  /// The first template parameter list in a declaration will have depth 0,
117198893Srdivacky  /// the second template parameter list will have depth 1, etc.
118198893Srdivacky  unsigned getDepth() const;
119234353Sdim
120243830Sdim  /// \brief Determine whether this template parameter list contains an
121243830Sdim  /// unexpanded parameter pack.
122243830Sdim  bool containsUnexpandedParameterPack() const {
123243830Sdim    return ContainsUnexpandedParameterPack;
124243830Sdim  }
125243830Sdim
126193326Sed  SourceLocation getTemplateLoc() const { return TemplateLoc; }
127193326Sed  SourceLocation getLAngleLoc() const { return LAngleLoc; }
128193326Sed  SourceLocation getRAngleLoc() const { return RAngleLoc; }
129193326Sed
130234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
131193326Sed    return SourceRange(TemplateLoc, RAngleLoc);
132193326Sed  }
133193326Sed};
134193326Sed
135239462Sdim/// \brief Stores a list of template parameters for a TemplateDecl and its
136239462Sdim/// derived classes. Suitable for creating on the stack.
137219077Sdimtemplate<size_t N>
138219077Sdimclass FixedSizeTemplateParameterList : public TemplateParameterList {
139219077Sdim  NamedDecl *Params[N];
140219077Sdim
141219077Sdimpublic:
142234353Sdim  FixedSizeTemplateParameterList(SourceLocation TemplateLoc,
143234353Sdim                                 SourceLocation LAngleLoc,
144219077Sdim                                 NamedDecl **Params, SourceLocation RAngleLoc) :
145219077Sdim    TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) {
146219077Sdim  }
147219077Sdim};
148219077Sdim
149195341Sed/// \brief A template argument list.
150195341Sedclass TemplateArgumentList {
151195341Sed  /// \brief The template argument list.
152195341Sed  ///
153195341Sed  /// The integer value will be non-zero to indicate that this
154208600Srdivacky  /// template argument list does own the pointer.
155218893Sdim  llvm::PointerIntPair<const TemplateArgument *, 1> Arguments;
156198092Srdivacky
157195341Sed  /// \brief The number of template arguments in this template
158195341Sed  /// argument list.
159218893Sdim  unsigned NumArguments;
160198092Srdivacky
161243830Sdim  TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
162243830Sdim  void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION;
163198092Srdivacky
164218893Sdim  TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs,
165218893Sdim                       bool Owned)
166218893Sdim    : Arguments(Args, Owned), NumArguments(NumArgs) { }
167210299Sed
168218893Sdimpublic:
169234353Sdim  /// \brief Type used to indicate that the template argument list itself is a
170218893Sdim  /// stack object. It does not own its template arguments.
171218893Sdim  enum OnStackType { OnStack };
172210299Sed
173218893Sdim  /// \brief Create a new template argument list that copies the given set of
174218893Sdim  /// template arguments.
175218893Sdim  static TemplateArgumentList *CreateCopy(ASTContext &Context,
176218893Sdim                                          const TemplateArgument *Args,
177218893Sdim                                          unsigned NumArgs);
178210299Sed
179218893Sdim  /// \brief Construct a new, temporary template argument list on the stack.
180218893Sdim  ///
181218893Sdim  /// The template argument list does not own the template arguments
182218893Sdim  /// provided.
183234353Sdim  explicit TemplateArgumentList(OnStackType,
184218893Sdim                                const TemplateArgument *Args, unsigned NumArgs)
185218893Sdim    : Arguments(Args, false), NumArguments(NumArgs) { }
186234353Sdim
187234353Sdim  /// \brief Produces a shallow copy of the given template argument list.
188234353Sdim  ///
189218893Sdim  /// This operation assumes that the input argument list outlives it.
190218893Sdim  /// This takes the list as a pointer to avoid looking like a copy
191218893Sdim  /// constructor, since this really really isn't safe to use that
192218893Sdim  /// way.
193218893Sdim  explicit TemplateArgumentList(const TemplateArgumentList *Other)
194218893Sdim    : Arguments(Other->data(), false), NumArguments(Other->size()) { }
195198092Srdivacky
196195341Sed  /// \brief Retrieve the template argument at a given index.
197198092Srdivacky  const TemplateArgument &get(unsigned Idx) const {
198218893Sdim    assert(Idx < NumArguments && "Invalid template argument index");
199218893Sdim    return data()[Idx];
200195341Sed  }
201198092Srdivacky
202195341Sed  /// \brief Retrieve the template argument at a given index.
203195341Sed  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
204198092Srdivacky
205249423Sdim  /// \brief Produce this as an array ref.
206249423Sdim  llvm::ArrayRef<TemplateArgument> asArray() const {
207249423Sdim    return llvm::ArrayRef<TemplateArgument>(data(), size());
208249423Sdim  }
209249423Sdim
210195341Sed  /// \brief Retrieve the number of template arguments in this
211195341Sed  /// template argument list.
212218893Sdim  unsigned size() const { return NumArguments; }
213198092Srdivacky
214218893Sdim  /// \brief Retrieve a pointer to the template argument list.
215218893Sdim  const TemplateArgument *data() const {
216218893Sdim    return Arguments.getPointer();
217195341Sed  }
218195341Sed};
219198092Srdivacky
220193326Sed//===----------------------------------------------------------------------===//
221193326Sed// Kinds of Templates
222193326Sed//===----------------------------------------------------------------------===//
223193326Sed
224239462Sdim/// \brief The base class of all kinds of template declarations (e.g.,
225239462Sdim/// class, function, etc.).
226239462Sdim///
227239462Sdim/// The TemplateDecl class stores the list of template parameters and a
228239462Sdim/// reference to the templated scoped declaration: the underlying AST node.
229193326Sedclass TemplateDecl : public NamedDecl {
230234353Sdim  virtual void anchor();
231193326Sedprotected:
232193326Sed  // This is probably never used.
233193326Sed  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
234193326Sed               DeclarationName Name)
235198092Srdivacky    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
236193326Sed
237193326Sed  // Construct a template decl with the given name and parameters.
238193326Sed  // Used when there is not templated element (tt-params, alias?).
239193326Sed  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
240193326Sed               DeclarationName Name, TemplateParameterList *Params)
241198092Srdivacky    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
242193326Sed
243193326Sed  // Construct a template decl with name, parameters, and templated element.
244193326Sed  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
245193326Sed               DeclarationName Name, TemplateParameterList *Params,
246193326Sed               NamedDecl *Decl)
247193326Sed    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
248193326Sed      TemplateParams(Params) { }
249193326Sedpublic:
250193326Sed  /// Get the list of template parameters
251193326Sed  TemplateParameterList *getTemplateParameters() const {
252193326Sed    return TemplateParams;
253193326Sed  }
254193326Sed
255193326Sed  /// Get the underlying, templated declaration.
256193326Sed  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
257193326Sed
258193326Sed  // Implement isa/cast/dyncast/etc.
259203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
260203955Srdivacky  static bool classofKind(Kind K) {
261210299Sed    return K >= firstTemplate && K <= lastTemplate;
262203955Srdivacky  }
263193326Sed
264234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
265210299Sed    return SourceRange(TemplateParams->getTemplateLoc(),
266210299Sed                       TemplatedDecl->getSourceRange().getEnd());
267210299Sed  }
268210299Sed
269193326Sedprotected:
270193326Sed  NamedDecl *TemplatedDecl;
271193326Sed  TemplateParameterList* TemplateParams;
272234353Sdim
273210299Sedpublic:
274210299Sed  /// \brief Initialize the underlying templated declaration and
275210299Sed  /// template parameters.
276210299Sed  void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
277210299Sed    assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
278210299Sed    assert(TemplateParams == 0 && "TemplateParams already set!");
279210299Sed    TemplatedDecl = templatedDecl;
280210299Sed    TemplateParams = templateParams;
281210299Sed  }
282193326Sed};
283198092Srdivacky
284198092Srdivacky/// \brief Provides information about a function template specialization,
285195341Sed/// which is a FunctionDecl that has been explicitly specialization or
286195341Sed/// instantiated from a function template.
287195341Sedclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
288218893Sdim  FunctionTemplateSpecializationInfo(FunctionDecl *FD,
289218893Sdim                                     FunctionTemplateDecl *Template,
290218893Sdim                                     TemplateSpecializationKind TSK,
291218893Sdim                                     const TemplateArgumentList *TemplateArgs,
292226633Sdim                       const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
293218893Sdim                                     SourceLocation POI)
294218893Sdim  : Function(FD),
295218893Sdim    Template(Template, TSK - 1),
296218893Sdim    TemplateArguments(TemplateArgs),
297218893Sdim    TemplateArgumentsAsWritten(TemplateArgsAsWritten),
298218893Sdim    PointOfInstantiation(POI) { }
299218893Sdim
300195341Sedpublic:
301218893Sdim  static FunctionTemplateSpecializationInfo *
302218893Sdim  Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
303218893Sdim         TemplateSpecializationKind TSK,
304218893Sdim         const TemplateArgumentList *TemplateArgs,
305218893Sdim         const TemplateArgumentListInfo *TemplateArgsAsWritten,
306226633Sdim         SourceLocation POI);
307218893Sdim
308198092Srdivacky  /// \brief The function template specialization that this structure
309195341Sed  /// describes.
310195341Sed  FunctionDecl *Function;
311198092Srdivacky
312198092Srdivacky  /// \brief The function template from which this function template
313195341Sed  /// specialization was generated.
314195341Sed  ///
315198092Srdivacky  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
316198092Srdivacky  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
317198092Srdivacky
318195341Sed  /// \brief The template arguments used to produce the function template
319195341Sed  /// specialization from the function template.
320195341Sed  const TemplateArgumentList *TemplateArguments;
321198092Srdivacky
322208600Srdivacky  /// \brief The template arguments as written in the sources, if provided.
323226633Sdim  const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
324208600Srdivacky
325198092Srdivacky  /// \brief The point at which this function template specialization was
326234353Sdim  /// first instantiated.
327198092Srdivacky  SourceLocation PointOfInstantiation;
328234353Sdim
329195341Sed  /// \brief Retrieve the template from which this function was specialized.
330195341Sed  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
331198092Srdivacky
332198092Srdivacky  /// \brief Determine what kind of template specialization this is.
333198092Srdivacky  TemplateSpecializationKind getTemplateSpecializationKind() const {
334198092Srdivacky    return (TemplateSpecializationKind)(Template.getInt() + 1);
335198092Srdivacky  }
336198092Srdivacky
337224145Sdim  bool isExplicitSpecialization() const {
338224145Sdim    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
339224145Sdim  }
340224145Sdim
341249423Sdim  /// \brief True if this declaration is an explicit specialization,
342249423Sdim  /// explicit instantiation declaration, or explicit instantiation
343249423Sdim  /// definition.
344249423Sdim  bool isExplicitInstantiationOrSpecialization() const {
345249423Sdim    switch (getTemplateSpecializationKind()) {
346249423Sdim    case TSK_ExplicitSpecialization:
347249423Sdim    case TSK_ExplicitInstantiationDeclaration:
348249423Sdim    case TSK_ExplicitInstantiationDefinition:
349249423Sdim      return true;
350249423Sdim
351249423Sdim    case TSK_Undeclared:
352249423Sdim    case TSK_ImplicitInstantiation:
353249423Sdim      return false;
354249423Sdim    }
355249423Sdim    llvm_unreachable("bad template specialization kind");
356249423Sdim  }
357249423Sdim
358198092Srdivacky  /// \brief Set the template specialization kind.
359198092Srdivacky  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
360198092Srdivacky    assert(TSK != TSK_Undeclared &&
361198092Srdivacky         "Cannot encode TSK_Undeclared for a function template specialization");
362198092Srdivacky    Template.setInt(TSK - 1);
363198092Srdivacky  }
364198092Srdivacky
365198092Srdivacky  /// \brief Retrieve the first point of instantiation of this function
366198092Srdivacky  /// template specialization.
367198092Srdivacky  ///
368198092Srdivacky  /// The point of instantiation may be an invalid source location if this
369198092Srdivacky  /// function has yet to be instantiated.
370234353Sdim  SourceLocation getPointOfInstantiation() const {
371234353Sdim    return PointOfInstantiation;
372198092Srdivacky  }
373234353Sdim
374198092Srdivacky  /// \brief Set the (first) point of instantiation of this function template
375198092Srdivacky  /// specialization.
376198092Srdivacky  void setPointOfInstantiation(SourceLocation POI) {
377198092Srdivacky    PointOfInstantiation = POI;
378195341Sed  }
379234353Sdim
380195341Sed  void Profile(llvm::FoldingSetNodeID &ID) {
381218893Sdim    Profile(ID, TemplateArguments->data(),
382218893Sdim            TemplateArguments->size(),
383198092Srdivacky            Function->getASTContext());
384195341Sed  }
385198092Srdivacky
386198092Srdivacky  static void
387198092Srdivacky  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
388198092Srdivacky          unsigned NumTemplateArgs, ASTContext &Context) {
389195341Sed    ID.AddInteger(NumTemplateArgs);
390195341Sed    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
391198092Srdivacky      TemplateArgs[Arg].Profile(ID, Context);
392198092Srdivacky  }
393195341Sed};
394198092Srdivacky
395234353Sdim/// \brief Provides information a specialization of a member of a class
396234353Sdim/// template, which may be a member function, static data member,
397234353Sdim/// member class or member enumeration.
398198092Srdivackyclass MemberSpecializationInfo {
399198092Srdivacky  // The member declaration from which this member was instantiated, and the
400198092Srdivacky  // manner in which the instantiation occurred (in the lower two bits).
401198092Srdivacky  llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
402234353Sdim
403198092Srdivacky  // The point at which this member was first instantiated.
404198092Srdivacky  SourceLocation PointOfInstantiation;
405234353Sdim
406198092Srdivackypublic:
407234353Sdim  explicit
408210299Sed  MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
409210299Sed                           SourceLocation POI = SourceLocation())
410210299Sed    : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
411234353Sdim    assert(TSK != TSK_Undeclared &&
412198092Srdivacky           "Cannot encode undeclared template specializations for members");
413198092Srdivacky  }
414234353Sdim
415198092Srdivacky  /// \brief Retrieve the member declaration from which this member was
416198092Srdivacky  /// instantiated.
417198092Srdivacky  NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
418234353Sdim
419198092Srdivacky  /// \brief Determine what kind of template specialization this is.
420198092Srdivacky  TemplateSpecializationKind getTemplateSpecializationKind() const {
421198092Srdivacky    return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
422198092Srdivacky  }
423234353Sdim
424249423Sdim  bool isExplicitSpecialization() const {
425249423Sdim    return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
426249423Sdim  }
427249423Sdim
428198092Srdivacky  /// \brief Set the template specialization kind.
429198092Srdivacky  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
430234353Sdim    assert(TSK != TSK_Undeclared &&
431198092Srdivacky           "Cannot encode undeclared template specializations for members");
432198092Srdivacky    MemberAndTSK.setInt(TSK - 1);
433198092Srdivacky  }
434234353Sdim
435234353Sdim  /// \brief Retrieve the first point of instantiation of this member.
436198092Srdivacky  /// If the point of instantiation is an invalid location, then this member
437198092Srdivacky  /// has not yet been instantiated.
438234353Sdim  SourceLocation getPointOfInstantiation() const {
439234353Sdim    return PointOfInstantiation;
440198092Srdivacky  }
441234353Sdim
442198092Srdivacky  /// \brief Set the first point of instantiation.
443198092Srdivacky  void setPointOfInstantiation(SourceLocation POI) {
444198092Srdivacky    PointOfInstantiation = POI;
445198092Srdivacky  }
446198092Srdivacky};
447207619Srdivacky
448207619Srdivacky/// \brief Provides information about a dependent function-template
449239462Sdim/// specialization declaration.
450207619Srdivacky///
451239462Sdim/// Since explicit function template specialization and instantiation
452239462Sdim/// declarations can only appear in namespace scope, and you can only
453239462Sdim/// specialize a member of a fully-specialized class, the only way to
454239462Sdim/// get one of these is in a friend declaration like the following:
455239462Sdim///
456239462Sdim/// \code
457239462Sdim///   template \<class T> void foo(T);
458239462Sdim///   template \<class T> class A {
459207619Srdivacky///     friend void foo<>(T);
460207619Srdivacky///   };
461239462Sdim/// \endcode
462207619Srdivackyclass DependentFunctionTemplateSpecializationInfo {
463249423Sdim  struct CA {
464249423Sdim    /// The number of potential template candidates.
465249423Sdim    unsigned NumTemplates;
466249423Sdim
467249423Sdim    /// The number of template arguments.
468249423Sdim    unsigned NumArgs;
469249423Sdim  };
470249423Sdim
471207619Srdivacky  union {
472207619Srdivacky    // Force sizeof to be a multiple of sizeof(void*) so that the
473207619Srdivacky    // trailing data is aligned.
474234353Sdim    void *Aligner;
475249423Sdim    struct CA d;
476207619Srdivacky  };
477207619Srdivacky
478207619Srdivacky  /// The locations of the left and right angle brackets.
479207619Srdivacky  SourceRange AngleLocs;
480207619Srdivacky
481207619Srdivacky  FunctionTemplateDecl * const *getTemplates() const {
482207619Srdivacky    return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
483207619Srdivacky  }
484207619Srdivacky
485207619Srdivackypublic:
486207619Srdivacky  DependentFunctionTemplateSpecializationInfo(
487207619Srdivacky                                 const UnresolvedSetImpl &Templates,
488207619Srdivacky                                 const TemplateArgumentListInfo &TemplateArgs);
489207619Srdivacky
490207619Srdivacky  /// \brief Returns the number of function templates that this might
491207619Srdivacky  /// be a specialization of.
492207619Srdivacky  unsigned getNumTemplates() const {
493207619Srdivacky    return d.NumTemplates;
494207619Srdivacky  }
495207619Srdivacky
496207619Srdivacky  /// \brief Returns the i'th template candidate.
497207619Srdivacky  FunctionTemplateDecl *getTemplate(unsigned I) const {
498207619Srdivacky    assert(I < getNumTemplates() && "template index out of range");
499207619Srdivacky    return getTemplates()[I];
500207619Srdivacky  }
501207619Srdivacky
502218893Sdim  /// \brief Returns the explicit template arguments that were given.
503218893Sdim  const TemplateArgumentLoc *getTemplateArgs() const {
504218893Sdim    return reinterpret_cast<const TemplateArgumentLoc*>(
505234353Sdim                                            &getTemplates()[getNumTemplates()]);
506218893Sdim  }
507218893Sdim
508207619Srdivacky  /// \brief Returns the number of explicit template arguments that were given.
509207619Srdivacky  unsigned getNumTemplateArgs() const {
510207619Srdivacky    return d.NumArgs;
511207619Srdivacky  }
512207619Srdivacky
513207619Srdivacky  /// \brief Returns the nth template argument.
514207619Srdivacky  const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
515207619Srdivacky    assert(I < getNumTemplateArgs() && "template arg index out of range");
516207619Srdivacky    return getTemplateArgs()[I];
517207619Srdivacky  }
518207619Srdivacky
519207619Srdivacky  SourceLocation getLAngleLoc() const {
520207619Srdivacky    return AngleLocs.getBegin();
521207619Srdivacky  }
522207619Srdivacky
523207619Srdivacky  SourceLocation getRAngleLoc() const {
524207619Srdivacky    return AngleLocs.getEnd();
525207619Srdivacky  }
526207619Srdivacky};
527234353Sdim
528212904Sdim/// Declaration of a redeclarable template.
529234353Sdimclass RedeclarableTemplateDecl : public TemplateDecl,
530234353Sdim                                 public Redeclarable<RedeclarableTemplateDecl>
531234353Sdim{
532234353Sdim  typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
533234353Sdim  virtual RedeclarableTemplateDecl *getNextRedeclaration() {
534234353Sdim    return RedeclLink.getNext();
535212904Sdim  }
536234353Sdim  virtual RedeclarableTemplateDecl *getPreviousDeclImpl() {
537234353Sdim    return getPreviousDecl();
538212904Sdim  }
539234353Sdim  virtual RedeclarableTemplateDecl *getMostRecentDeclImpl() {
540234353Sdim    return getMostRecentDecl();
541212904Sdim  }
542212904Sdim
543193326Sedprotected:
544212904Sdim  template <typename EntryType> struct SpecEntryTraits {
545212904Sdim    typedef EntryType DeclType;
546198092Srdivacky
547234353Sdim    static DeclType *getMostRecentDecl(EntryType *D) {
548234353Sdim      return D->getMostRecentDecl();
549212904Sdim    }
550212904Sdim  };
551198092Srdivacky
552212904Sdim  template <typename EntryType,
553212904Sdim            typename _SETraits = SpecEntryTraits<EntryType>,
554212904Sdim            typename _DeclType = typename _SETraits::DeclType>
555212904Sdim  class SpecIterator : public std::iterator<std::forward_iterator_tag,
556212904Sdim                                            _DeclType*, ptrdiff_t,
557212904Sdim                                            _DeclType*, _DeclType*> {
558212904Sdim    typedef _SETraits SETraits;
559212904Sdim    typedef _DeclType DeclType;
560212904Sdim
561239462Sdim    typedef typename llvm::FoldingSetVector<EntryType>::iterator
562239462Sdim      SetIteratorType;
563212904Sdim
564212904Sdim    SetIteratorType SetIter;
565212904Sdim
566212904Sdim  public:
567212904Sdim    SpecIterator() : SetIter() {}
568212904Sdim    SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
569212904Sdim
570212904Sdim    DeclType *operator*() const {
571234353Sdim      return SETraits::getMostRecentDecl(&*SetIter);
572212904Sdim    }
573212904Sdim    DeclType *operator->() const { return **this; }
574212904Sdim
575212904Sdim    SpecIterator &operator++() { ++SetIter; return *this; }
576212904Sdim    SpecIterator operator++(int) {
577212904Sdim      SpecIterator tmp(*this);
578212904Sdim      ++(*this);
579212904Sdim      return tmp;
580212904Sdim    }
581212904Sdim
582212904Sdim    bool operator==(SpecIterator Other) const {
583212904Sdim      return SetIter == Other.SetIter;
584212904Sdim    }
585212904Sdim    bool operator!=(SpecIterator Other) const {
586212904Sdim      return SetIter != Other.SetIter;
587212904Sdim    }
588212904Sdim  };
589212904Sdim
590212904Sdim  template <typename EntryType>
591249423Sdim  static SpecIterator<EntryType>
592239462Sdim  makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
593212904Sdim    return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
594212904Sdim  }
595212904Sdim
596212904Sdim  template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
597239462Sdim  findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
598212904Sdim                         const TemplateArgument *Args, unsigned NumArgs,
599212904Sdim                         void *&InsertPos);
600212904Sdim
601212904Sdim  struct CommonBase {
602212904Sdim    CommonBase() : InstantiatedFromMember(0, false) { }
603212904Sdim
604212904Sdim    /// \brief The template from which this was most
605198092Srdivacky    /// directly instantiated (or null).
606198092Srdivacky    ///
607212904Sdim    /// The boolean value indicates whether this template
608198092Srdivacky    /// was explicitly specialized.
609212904Sdim    llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
610212904Sdim      InstantiatedFromMember;
611195341Sed  };
612198092Srdivacky
613234353Sdim  /// \brief Pointer to the common data shared by all declarations of this
614234353Sdim  /// template.
615249423Sdim  mutable CommonBase *Common;
616234353Sdim
617212904Sdim  /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
618212904Sdim  /// the same template. Calling this routine may implicitly allocate memory
619212904Sdim  /// for the common pointer.
620249423Sdim  CommonBase *getCommonPtr() const;
621198092Srdivacky
622249423Sdim  virtual CommonBase *newCommon(ASTContext &C) const = 0;
623198092Srdivacky
624212904Sdim  // Construct a template decl with name, parameters, and templated element.
625212904Sdim  RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
626212904Sdim                           DeclarationName Name, TemplateParameterList *Params,
627212904Sdim                           NamedDecl *Decl)
628234353Sdim    : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { }
629212904Sdim
630193326Sedpublic:
631212904Sdim  template <class decl_type> friend class RedeclarableTemplate;
632198092Srdivacky
633239462Sdim  /// \brief Retrieves the canonical declaration of this template.
634263508Sdim  RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDecl(); }
635263508Sdim  const RedeclarableTemplateDecl *getCanonicalDecl() const {
636263508Sdim    return getFirstDecl();
637193326Sed  }
638193326Sed
639234353Sdim  /// \brief Determines whether this template was a specialization of a
640212904Sdim  /// member template.
641212904Sdim  ///
642212904Sdim  /// In the following example, the function template \c X<int>::f and the
643212904Sdim  /// member template \c X<int>::Inner are member specializations.
644212904Sdim  ///
645212904Sdim  /// \code
646212904Sdim  /// template<typename T>
647212904Sdim  /// struct X {
648212904Sdim  ///   template<typename U> void f(T, U);
649212904Sdim  ///   template<typename U> struct Inner;
650212904Sdim  /// };
651212904Sdim  ///
652212904Sdim  /// template<> template<typename T>
653212904Sdim  /// void X<int>::f(int, T);
654212904Sdim  /// template<> template<typename T>
655212904Sdim  /// struct X<int>::Inner { /* ... */ };
656212904Sdim  /// \endcode
657249423Sdim  bool isMemberSpecialization() const {
658212904Sdim    return getCommonPtr()->InstantiatedFromMember.getInt();
659212904Sdim  }
660234353Sdim
661212904Sdim  /// \brief Note that this member template is a specialization.
662212904Sdim  void setMemberSpecialization() {
663212904Sdim    assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
664212904Sdim           "Only member templates can be member template specializations");
665212904Sdim    getCommonPtr()->InstantiatedFromMember.setInt(true);
666212904Sdim  }
667234353Sdim
668234353Sdim  /// \brief Retrieve the member template from which this template was
669234353Sdim  /// instantiated, or NULL if this template was not instantiated from a
670234353Sdim  /// member template.
671234353Sdim  ///
672234353Sdim  /// A template is instantiated from a member template when the member
673234353Sdim  /// template itself is part of a class template (or member thereof). For
674234353Sdim  /// example, given
675234353Sdim  ///
676234353Sdim  /// \code
677234353Sdim  /// template<typename T>
678234353Sdim  /// struct X {
679234353Sdim  ///   template<typename U> void f(T, U);
680234353Sdim  /// };
681234353Sdim  ///
682234353Sdim  /// void test(X<int> x) {
683234353Sdim  ///   x.f(1, 'a');
684234353Sdim  /// };
685234353Sdim  /// \endcode
686234353Sdim  ///
687234353Sdim  /// \c X<int>::f is a FunctionTemplateDecl that describes the function
688234353Sdim  /// template
689234353Sdim  ///
690234353Sdim  /// \code
691234353Sdim  /// template<typename U> void X<int>::f(int, U);
692234353Sdim  /// \endcode
693234353Sdim  ///
694234353Sdim  /// which was itself created during the instantiation of \c X<int>. Calling
695234353Sdim  /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
696239462Sdim  /// retrieve the FunctionTemplateDecl for the original template \c f within
697234353Sdim  /// the class template \c X<T>, i.e.,
698234353Sdim  ///
699234353Sdim  /// \code
700234353Sdim  /// template<typename T>
701234353Sdim  /// template<typename U>
702234353Sdim  /// void X<T>::f(T, U);
703234353Sdim  /// \endcode
704249423Sdim  RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
705234353Sdim    return getCommonPtr()->InstantiatedFromMember.getPointer();
706212904Sdim  }
707212904Sdim
708234353Sdim  void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
709234353Sdim    assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
710234353Sdim    getCommonPtr()->InstantiatedFromMember.setPointer(TD);
711234353Sdim  }
712212904Sdim
713234353Sdim  typedef redeclarable_base::redecl_iterator redecl_iterator;
714234353Sdim  using redeclarable_base::redecls_begin;
715234353Sdim  using redeclarable_base::redecls_end;
716234353Sdim  using redeclarable_base::getPreviousDecl;
717234353Sdim  using redeclarable_base::getMostRecentDecl;
718263508Sdim  using redeclarable_base::isFirstDecl;
719234353Sdim
720212904Sdim  // Implement isa/cast/dyncast/etc.
721212904Sdim  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
722212904Sdim  static bool classofKind(Kind K) {
723212904Sdim    return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
724212904Sdim  }
725212904Sdim
726234353Sdim  friend class ASTReader;
727212904Sdim  friend class ASTDeclReader;
728212904Sdim  friend class ASTDeclWriter;
729212904Sdim};
730212904Sdim
731212904Sdimtemplate <> struct RedeclarableTemplateDecl::
732212904SdimSpecEntryTraits<FunctionTemplateSpecializationInfo> {
733212904Sdim  typedef FunctionDecl DeclType;
734212904Sdim
735212904Sdim  static DeclType *
736234353Sdim  getMostRecentDecl(FunctionTemplateSpecializationInfo *I) {
737234353Sdim    return I->Function->getMostRecentDecl();
738198092Srdivacky  }
739212904Sdim};
740212904Sdim
741212904Sdim/// Declaration of a template function.
742234353Sdimclass FunctionTemplateDecl : public RedeclarableTemplateDecl {
743212904Sdim  static void DeallocateCommon(void *Ptr);
744212904Sdim
745212904Sdimprotected:
746212904Sdim  /// \brief Data that is common to all of the declarations of a given
747212904Sdim  /// function template.
748212904Sdim  struct Common : CommonBase {
749263508Sdim    Common() : InjectedArgs(), LazySpecializations() { }
750234353Sdim
751212904Sdim    /// \brief The function template specializations for this function
752212904Sdim    /// template, including explicit specializations and instantiations.
753239462Sdim    llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
754234353Sdim
755221345Sdim    /// \brief The set of "injected" template arguments used within this
756221345Sdim    /// function template.
757221345Sdim    ///
758221345Sdim    /// This pointer refers to the template arguments (there are as
759221345Sdim    /// many template arguments as template parameaters) for the function
760221345Sdim    /// template, and is allocated lazily, since most function templates do not
761221345Sdim    /// require the use of this information.
762221345Sdim    TemplateArgument *InjectedArgs;
763263508Sdim
764263508Sdim    /// \brief If non-null, points to an array of specializations known only
765263508Sdim    /// by their external declaration IDs.
766263508Sdim    ///
767263508Sdim    /// The first value in the array is the number of of specializations
768263508Sdim    /// that follow.
769263508Sdim    uint32_t *LazySpecializations;
770212904Sdim  };
771212904Sdim
772212904Sdim  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
773212904Sdim                       TemplateParameterList *Params, NamedDecl *Decl)
774212904Sdim    : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
775212904Sdim
776249423Sdim  CommonBase *newCommon(ASTContext &C) const;
777212904Sdim
778249423Sdim  Common *getCommonPtr() const {
779212904Sdim    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
780212904Sdim  }
781212904Sdim
782218893Sdim  friend class FunctionDecl;
783212904Sdim
784263508Sdim  /// \brief Load any lazily-loaded specializations from the external source.
785263508Sdim  void LoadLazySpecializations() const;
786263508Sdim
787212904Sdim  /// \brief Retrieve the set of function template specializations of this
788212904Sdim  /// function template.
789239462Sdim  llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
790263508Sdim  getSpecializations() const;
791221345Sdim
792221345Sdim  /// \brief Add a specialization of this function template.
793221345Sdim  ///
794239462Sdim  /// \param InsertPos Insert position in the FoldingSetVector, must have been
795221345Sdim  ///        retrieved by an earlier call to findSpecialization().
796221345Sdim  void addSpecialization(FunctionTemplateSpecializationInfo* Info,
797221345Sdim                         void *InsertPos);
798234353Sdim
799212904Sdimpublic:
800212904Sdim  /// Get the underlying function declaration of the template.
801212904Sdim  FunctionDecl *getTemplatedDecl() const {
802212904Sdim    return static_cast<FunctionDecl*>(TemplatedDecl);
803198092Srdivacky  }
804212904Sdim
805212904Sdim  /// Returns whether this template declaration defines the primary
806212904Sdim  /// pattern.
807212904Sdim  bool isThisDeclarationADefinition() const {
808212904Sdim    return getTemplatedDecl()->isThisDeclarationADefinition();
809212904Sdim  }
810212904Sdim
811212904Sdim  /// \brief Return the specialization with the provided arguments if it exists,
812212904Sdim  /// otherwise return the insertion point.
813212904Sdim  FunctionDecl *findSpecialization(const TemplateArgument *Args,
814212904Sdim                                   unsigned NumArgs, void *&InsertPos);
815212904Sdim
816212904Sdim  FunctionTemplateDecl *getCanonicalDecl() {
817234353Sdim    return cast<FunctionTemplateDecl>(
818234353Sdim             RedeclarableTemplateDecl::getCanonicalDecl());
819212904Sdim  }
820212904Sdim  const FunctionTemplateDecl *getCanonicalDecl() const {
821234353Sdim    return cast<FunctionTemplateDecl>(
822234353Sdim             RedeclarableTemplateDecl::getCanonicalDecl());
823212904Sdim  }
824212904Sdim
825212904Sdim  /// \brief Retrieve the previous declaration of this function template, or
826212904Sdim  /// NULL if no such declaration exists.
827234353Sdim  FunctionTemplateDecl *getPreviousDecl() {
828234353Sdim    return cast_or_null<FunctionTemplateDecl>(
829263508Sdim             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
830212904Sdim  }
831212904Sdim
832212904Sdim  /// \brief Retrieve the previous declaration of this function template, or
833212904Sdim  /// NULL if no such declaration exists.
834234353Sdim  const FunctionTemplateDecl *getPreviousDecl() const {
835234353Sdim    return cast_or_null<FunctionTemplateDecl>(
836263508Sdim       static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
837212904Sdim  }
838212904Sdim
839212904Sdim  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
840234353Sdim    return cast_or_null<FunctionTemplateDecl>(
841234353Sdim             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
842212904Sdim  }
843212904Sdim
844212904Sdim  typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
845212904Sdim
846249423Sdim  spec_iterator spec_begin() const {
847212904Sdim    return makeSpecIterator(getSpecializations(), false);
848212904Sdim  }
849212904Sdim
850249423Sdim  spec_iterator spec_end() const {
851212904Sdim    return makeSpecIterator(getSpecializations(), true);
852212904Sdim  }
853212904Sdim
854221345Sdim  /// \brief Retrieve the "injected" template arguments that correspond to the
855221345Sdim  /// template parameters of this function template.
856234353Sdim  ///
857221345Sdim  /// Although the C++ standard has no notion of the "injected" template
858221345Sdim  /// arguments for a function template, the notion is convenient when
859221345Sdim  /// we need to perform substitutions inside the definition of a function
860234353Sdim  /// template.
861263508Sdim  ArrayRef<TemplateArgument> getInjectedTemplateArgs();
862234353Sdim
863221345Sdim  /// \brief Create a function template node.
864193326Sed  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
865193326Sed                                      SourceLocation L,
866193326Sed                                      DeclarationName Name,
867193326Sed                                      TemplateParameterList *Params,
868193326Sed                                      NamedDecl *Decl);
869193326Sed
870221345Sdim  /// \brief Create an empty function template node.
871234353Sdim  static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
872221345Sdim
873193326Sed  // Implement isa/cast/dyncast support
874203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
875203955Srdivacky  static bool classofKind(Kind K) { return K == FunctionTemplate; }
876210299Sed
877212904Sdim  friend class ASTDeclReader;
878212904Sdim  friend class ASTDeclWriter;
879193326Sed};
880193326Sed
881193326Sed//===----------------------------------------------------------------------===//
882193326Sed// Kinds of Template Parameters
883193326Sed//===----------------------------------------------------------------------===//
884193326Sed
885239462Sdim/// \brief Defines the position of a template parameter within a template
886239462Sdim/// parameter list.
887239462Sdim///
888239462Sdim/// Because template parameter can be listed
889193326Sed/// sequentially for out-of-line template members, each template parameter is
890193326Sed/// given a Depth - the nesting of template parameter scopes - and a Position -
891193326Sed/// the occurrence within the parameter list.
892193326Sed/// This class is inheritedly privately by different kinds of template
893193326Sed/// parameters and is not part of the Decl hierarchy. Just a facility.
894198092Srdivackyclass TemplateParmPosition {
895193326Sedprotected:
896193326Sed  // FIXME: This should probably never be called, but it's here as
897193326Sed  TemplateParmPosition()
898193326Sed    : Depth(0), Position(0)
899226633Sdim  { /* llvm_unreachable("Cannot create positionless template parameter"); */ }
900193326Sed
901193326Sed  TemplateParmPosition(unsigned D, unsigned P)
902193326Sed    : Depth(D), Position(P)
903193326Sed  { }
904193326Sed
905193326Sed  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
906193326Sed  // position? Maybe?
907193326Sed  unsigned Depth;
908193326Sed  unsigned Position;
909193326Sed
910193326Sedpublic:
911193326Sed  /// Get the nesting depth of the template parameter.
912193326Sed  unsigned getDepth() const { return Depth; }
913210299Sed  void setDepth(unsigned D) { Depth = D; }
914193326Sed
915193326Sed  /// Get the position of the template parameter within its parameter list.
916193326Sed  unsigned getPosition() const { return Position; }
917210299Sed  void setPosition(unsigned P) { Position = P; }
918198092Srdivacky
919193576Sed  /// Get the index of the template parameter within its parameter list.
920193576Sed  unsigned getIndex() const { return Position; }
921193326Sed};
922193326Sed
923239462Sdim/// \brief Declaration of a template type parameter.
924239462Sdim///
925239462Sdim/// For example, "T" in
926239462Sdim/// \code
927193326Sed/// template<typename T> class vector;
928239462Sdim/// \endcode
929193326Sedclass TemplateTypeParmDecl : public TypeDecl {
930193326Sed  /// \brief Whether this template type parameter was declaration with
931239462Sdim  /// the 'typename' keyword.
932239462Sdim  ///
933239462Sdim  /// If false, it was declared with the 'class' keyword.
934193326Sed  bool Typename : 1;
935193326Sed
936193326Sed  /// \brief Whether this template type parameter inherited its
937193326Sed  /// default argument.
938193326Sed  bool InheritedDefault : 1;
939193326Sed
940193326Sed  /// \brief The default template argument, if any.
941200583Srdivacky  TypeSourceInfo *DefaultArgument;
942193326Sed
943221345Sdim  TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
944221345Sdim                       SourceLocation IdLoc, IdentifierInfo *Id,
945221345Sdim                       bool Typename)
946221345Sdim    : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
947221345Sdim      InheritedDefault(false), DefaultArgument() { }
948193326Sed
949219077Sdim  /// Sema creates these on the stack during auto type deduction.
950219077Sdim  friend class Sema;
951219077Sdim
952193326Sedpublic:
953218893Sdim  static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
954221345Sdim                                      SourceLocation KeyLoc,
955221345Sdim                                      SourceLocation NameLoc,
956221345Sdim                                      unsigned D, unsigned P,
957194179Sed                                      IdentifierInfo *Id, bool Typename,
958194179Sed                                      bool ParameterPack);
959234353Sdim  static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
960234353Sdim                                                  unsigned ID);
961193326Sed
962193326Sed  /// \brief Whether this template type parameter was declared with
963239462Sdim  /// the 'typename' keyword.
964239462Sdim  ///
965239462Sdim  /// If not, it was declared with the 'class' keyword.
966193326Sed  bool wasDeclaredWithTypename() const { return Typename; }
967193326Sed
968193326Sed  /// \brief Determine whether this template parameter has a default
969193326Sed  /// argument.
970198893Srdivacky  bool hasDefaultArgument() const { return DefaultArgument != 0; }
971193326Sed
972193326Sed  /// \brief Retrieve the default argument, if any.
973198893Srdivacky  QualType getDefaultArgument() const { return DefaultArgument->getType(); }
974193326Sed
975198893Srdivacky  /// \brief Retrieves the default argument's source information, if any.
976200583Srdivacky  TypeSourceInfo *getDefaultArgumentInfo() const { return DefaultArgument; }
977193326Sed
978198893Srdivacky  /// \brief Retrieves the location of the default argument declaration.
979198893Srdivacky  SourceLocation getDefaultArgumentLoc() const;
980198893Srdivacky
981193326Sed  /// \brief Determines whether the default argument was inherited
982193326Sed  /// from a previous declaration of this template.
983193326Sed  bool defaultArgumentWasInherited() const { return InheritedDefault; }
984193326Sed
985193326Sed  /// \brief Set the default argument for this template parameter, and
986193326Sed  /// whether that default argument was inherited from another
987193326Sed  /// declaration.
988200583Srdivacky  void setDefaultArgument(TypeSourceInfo *DefArg, bool Inherited) {
989193326Sed    DefaultArgument = DefArg;
990193326Sed    InheritedDefault = Inherited;
991193326Sed  }
992193326Sed
993198893Srdivacky  /// \brief Removes the default argument of this template parameter.
994198893Srdivacky  void removeDefaultArgument() {
995198893Srdivacky    DefaultArgument = 0;
996198893Srdivacky    InheritedDefault = false;
997198893Srdivacky  }
998234353Sdim
999210299Sed  /// \brief Set whether this template type parameter was declared with
1000210299Sed  /// the 'typename' or 'class' keyword.
1001210299Sed  void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1002198893Srdivacky
1003198893Srdivacky  /// \brief Retrieve the depth of the template parameter.
1004198893Srdivacky  unsigned getDepth() const;
1005234353Sdim
1006198893Srdivacky  /// \brief Retrieve the index of the template parameter.
1007198893Srdivacky  unsigned getIndex() const;
1008198893Srdivacky
1009194179Sed  /// \brief Returns whether this is a parameter pack.
1010221345Sdim  bool isParameterPack() const;
1011194179Sed
1012234353Sdim  SourceRange getSourceRange() const LLVM_READONLY;
1013221345Sdim
1014193326Sed  // Implement isa/cast/dyncast/etc.
1015203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1016203955Srdivacky  static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1017193326Sed};
1018193326Sed
1019193326Sed/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1020193326Sed/// e.g., "Size" in
1021193326Sed/// @code
1022193326Sed/// template<int Size> class array { };
1023193326Sed/// @endcode
1024193326Sedclass NonTypeTemplateParmDecl
1025218893Sdim  : public DeclaratorDecl, protected TemplateParmPosition {
1026210299Sed  /// \brief The default template argument, if any, and whether or not
1027210299Sed  /// it was inherited.
1028210299Sed  llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
1029193326Sed
1030218893Sdim  // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1031218893Sdim  // down here to save memory.
1032234353Sdim
1033218893Sdim  /// \brief Whether this non-type template parameter is a parameter pack.
1034218893Sdim  bool ParameterPack;
1035234353Sdim
1036234353Sdim  /// \brief Whether this non-type template parameter is an "expanded"
1037218893Sdim  /// parameter pack, meaning that its type is a pack expansion and we
1038218893Sdim  /// already know the set of types that expansion expands to.
1039218893Sdim  bool ExpandedParameterPack;
1040234353Sdim
1041218893Sdim  /// \brief The number of types in an expanded parameter pack.
1042218893Sdim  unsigned NumExpandedTypes;
1043234353Sdim
1044221345Sdim  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1045221345Sdim                          SourceLocation IdLoc, unsigned D, unsigned P,
1046221345Sdim                          IdentifierInfo *Id, QualType T,
1047218893Sdim                          bool ParameterPack, TypeSourceInfo *TInfo)
1048221345Sdim    : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1049218893Sdim      TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
1050218893Sdim      ParameterPack(ParameterPack), ExpandedParameterPack(false),
1051218893Sdim      NumExpandedTypes(0)
1052193326Sed  { }
1053193326Sed
1054221345Sdim  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1055221345Sdim                          SourceLocation IdLoc, unsigned D, unsigned P,
1056221345Sdim                          IdentifierInfo *Id, QualType T,
1057218893Sdim                          TypeSourceInfo *TInfo,
1058218893Sdim                          const QualType *ExpandedTypes,
1059218893Sdim                          unsigned NumExpandedTypes,
1060218893Sdim                          TypeSourceInfo **ExpandedTInfos);
1061218893Sdim
1062218893Sdim  friend class ASTDeclReader;
1063234353Sdim
1064193326Sedpublic:
1065193326Sed  static NonTypeTemplateParmDecl *
1066221345Sdim  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1067221345Sdim         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1068221345Sdim         QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1069193326Sed
1070218893Sdim  static NonTypeTemplateParmDecl *
1071221345Sdim  Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1072221345Sdim         SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1073221345Sdim         QualType T, TypeSourceInfo *TInfo,
1074218893Sdim         const QualType *ExpandedTypes, unsigned NumExpandedTypes,
1075218893Sdim         TypeSourceInfo **ExpandedTInfos);
1076218893Sdim
1077234353Sdim  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1078234353Sdim                                                     unsigned ID);
1079234353Sdim  static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1080234353Sdim                                                     unsigned ID,
1081234353Sdim                                                     unsigned NumExpandedTypes);
1082234353Sdim
1083193326Sed  using TemplateParmPosition::getDepth;
1084210299Sed  using TemplateParmPosition::setDepth;
1085193326Sed  using TemplateParmPosition::getPosition;
1086210299Sed  using TemplateParmPosition::setPosition;
1087193576Sed  using TemplateParmPosition::getIndex;
1088198092Srdivacky
1089234353Sdim  SourceRange getSourceRange() const LLVM_READONLY;
1090218893Sdim
1091193326Sed  /// \brief Determine whether this template parameter has a default
1092193326Sed  /// argument.
1093210299Sed  bool hasDefaultArgument() const {
1094210299Sed    return DefaultArgumentAndInherited.getPointer() != 0;
1095210299Sed  }
1096193326Sed
1097193326Sed  /// \brief Retrieve the default argument, if any.
1098210299Sed  Expr *getDefaultArgument() const {
1099210299Sed    return DefaultArgumentAndInherited.getPointer();
1100210299Sed  }
1101193326Sed
1102193326Sed  /// \brief Retrieve the location of the default argument, if any.
1103193326Sed  SourceLocation getDefaultArgumentLoc() const;
1104193326Sed
1105210299Sed  /// \brief Determines whether the default argument was inherited
1106210299Sed  /// from a previous declaration of this template.
1107210299Sed  bool defaultArgumentWasInherited() const {
1108210299Sed    return DefaultArgumentAndInherited.getInt();
1109193326Sed  }
1110193326Sed
1111210299Sed  /// \brief Set the default argument for this template parameter, and
1112210299Sed  /// whether that default argument was inherited from another
1113210299Sed  /// declaration.
1114210299Sed  void setDefaultArgument(Expr *DefArg, bool Inherited) {
1115210299Sed    DefaultArgumentAndInherited.setPointer(DefArg);
1116210299Sed    DefaultArgumentAndInherited.setInt(Inherited);
1117210299Sed  }
1118210299Sed
1119210299Sed  /// \brief Removes the default argument of this template parameter.
1120210299Sed  void removeDefaultArgument() {
1121210299Sed    DefaultArgumentAndInherited.setPointer(0);
1122210299Sed    DefaultArgumentAndInherited.setInt(false);
1123210299Sed  }
1124210299Sed
1125218893Sdim  /// \brief Whether this parameter is a non-type template parameter pack.
1126218893Sdim  ///
1127218893Sdim  /// If the parameter is a parameter pack, the type may be a
1128218893Sdim  /// \c PackExpansionType. In the following example, the \c Dims parameter
1129218893Sdim  /// is a parameter pack (whose type is 'unsigned').
1130218893Sdim  ///
1131218893Sdim  /// \code
1132218893Sdim  /// template<typename T, unsigned ...Dims> struct multi_array;
1133218893Sdim  /// \endcode
1134218893Sdim  bool isParameterPack() const { return ParameterPack; }
1135234353Sdim
1136243830Sdim  /// \brief Whether this parameter pack is a pack expansion.
1137243830Sdim  ///
1138243830Sdim  /// A non-type template parameter pack is a pack expansion if its type
1139243830Sdim  /// contains an unexpanded parameter pack. In this case, we will have
1140243830Sdim  /// built a PackExpansionType wrapping the type.
1141243830Sdim  bool isPackExpansion() const {
1142243830Sdim    return ParameterPack && getType()->getAs<PackExpansionType>();
1143243830Sdim  }
1144243830Sdim
1145218893Sdim  /// \brief Whether this parameter is a non-type template parameter pack
1146243830Sdim  /// that has a known list of different types at different positions.
1147218893Sdim  ///
1148218893Sdim  /// A parameter pack is an expanded parameter pack when the original
1149218893Sdim  /// parameter pack's type was itself a pack expansion, and that expansion
1150218893Sdim  /// has already been expanded. For example, given:
1151218893Sdim  ///
1152218893Sdim  /// \code
1153218893Sdim  /// template<typename ...Types>
1154218893Sdim  /// struct X {
1155218893Sdim  ///   template<Types ...Values>
1156218893Sdim  ///   struct Y { /* ... */ };
1157218893Sdim  /// };
1158218893Sdim  /// \endcode
1159234353Sdim  ///
1160218893Sdim  /// The parameter pack \c Values has a \c PackExpansionType as its type,
1161218893Sdim  /// which expands \c Types. When \c Types is supplied with template arguments
1162234353Sdim  /// by instantiating \c X, the instantiation of \c Values becomes an
1163234353Sdim  /// expanded parameter pack. For example, instantiating
1164218893Sdim  /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1165218893Sdim  /// pack with expansion types \c int and \c unsigned int.
1166218893Sdim  ///
1167234353Sdim  /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1168218893Sdim  /// return the expansion types.
1169218893Sdim  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1170234353Sdim
1171234353Sdim  /// \brief Retrieves the number of expansion types in an expanded parameter
1172234353Sdim  /// pack.
1173218893Sdim  unsigned getNumExpansionTypes() const {
1174218893Sdim    assert(ExpandedParameterPack && "Not an expansion parameter pack");
1175218893Sdim    return NumExpandedTypes;
1176218893Sdim  }
1177218893Sdim
1178234353Sdim  /// \brief Retrieve a particular expansion type within an expanded parameter
1179218893Sdim  /// pack.
1180218893Sdim  QualType getExpansionType(unsigned I) const {
1181218893Sdim    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1182218893Sdim    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
1183218893Sdim    return QualType::getFromOpaquePtr(TypesAndInfos[2*I]);
1184218893Sdim  }
1185218893Sdim
1186234353Sdim  /// \brief Retrieve a particular expansion type source info within an
1187218893Sdim  /// expanded parameter pack.
1188218893Sdim  TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
1189218893Sdim    assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1190218893Sdim    void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
1191218893Sdim    return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]);
1192218893Sdim  }
1193218893Sdim
1194193326Sed  // Implement isa/cast/dyncast/etc.
1195203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1196203955Srdivacky  static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1197193326Sed};
1198193326Sed
1199193326Sed/// TemplateTemplateParmDecl - Declares a template template parameter,
1200193326Sed/// e.g., "T" in
1201193326Sed/// @code
1202193326Sed/// template <template <typename> class T> class container { };
1203193326Sed/// @endcode
1204193326Sed/// A template template parameter is a TemplateDecl because it defines the
1205193326Sed/// name of a template and the template parameters allowable for substitution.
1206234353Sdimclass TemplateTemplateParmDecl : public TemplateDecl,
1207234353Sdim                                 protected TemplateParmPosition
1208234353Sdim{
1209234353Sdim  virtual void anchor();
1210193326Sed
1211210299Sed  /// DefaultArgument - The default template argument, if any.
1212199482Srdivacky  TemplateArgumentLoc DefaultArgument;
1213210299Sed  /// Whether or not the default argument was inherited.
1214210299Sed  bool DefaultArgumentWasInherited;
1215193326Sed
1216218893Sdim  /// \brief Whether this parameter is a parameter pack.
1217218893Sdim  bool ParameterPack;
1218234353Sdim
1219243830Sdim  /// \brief Whether this template template parameter is an "expanded"
1220243830Sdim  /// parameter pack, meaning that it is a pack expansion and we
1221243830Sdim  /// already know the set of template parameters that expansion expands to.
1222243830Sdim  bool ExpandedParameterPack;
1223243830Sdim
1224243830Sdim  /// \brief The number of parameters in an expanded parameter pack.
1225243830Sdim  unsigned NumExpandedParams;
1226243830Sdim
1227193326Sed  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
1228218893Sdim                           unsigned D, unsigned P, bool ParameterPack,
1229193326Sed                           IdentifierInfo *Id, TemplateParameterList *Params)
1230193326Sed    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1231210299Sed      TemplateParmPosition(D, P), DefaultArgument(),
1232243830Sdim      DefaultArgumentWasInherited(false), ParameterPack(ParameterPack),
1233243830Sdim      ExpandedParameterPack(false), NumExpandedParams(0)
1234193326Sed    { }
1235193326Sed
1236243830Sdim  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
1237243830Sdim                           unsigned D, unsigned P,
1238243830Sdim                           IdentifierInfo *Id, TemplateParameterList *Params,
1239243830Sdim                           unsigned NumExpansions,
1240243830Sdim                           TemplateParameterList * const *Expansions);
1241243830Sdim
1242193326Sedpublic:
1243218893Sdim  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
1244193326Sed                                          SourceLocation L, unsigned D,
1245218893Sdim                                          unsigned P, bool ParameterPack,
1246218893Sdim                                          IdentifierInfo *Id,
1247193326Sed                                          TemplateParameterList *Params);
1248243830Sdim  static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
1249243830Sdim                                          SourceLocation L, unsigned D,
1250243830Sdim                                          unsigned P,
1251243830Sdim                                          IdentifierInfo *Id,
1252243830Sdim                                          TemplateParameterList *Params,
1253249423Sdim                                 ArrayRef<TemplateParameterList *> Expansions);
1254193326Sed
1255243830Sdim  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
1256234353Sdim                                                      unsigned ID);
1257243830Sdim  static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
1258243830Sdim                                                      unsigned ID,
1259243830Sdim                                                      unsigned NumExpansions);
1260234353Sdim
1261193326Sed  using TemplateParmPosition::getDepth;
1262193326Sed  using TemplateParmPosition::getPosition;
1263193576Sed  using TemplateParmPosition::getIndex;
1264198092Srdivacky
1265218893Sdim  /// \brief Whether this template template parameter is a template
1266218893Sdim  /// parameter pack.
1267218893Sdim  ///
1268218893Sdim  /// \code
1269218893Sdim  /// template<template <class T> ...MetaFunctions> struct Apply;
1270218893Sdim  /// \endcode
1271218893Sdim  bool isParameterPack() const { return ParameterPack; }
1272218893Sdim
1273243830Sdim  /// \brief Whether this parameter pack is a pack expansion.
1274243830Sdim  ///
1275243830Sdim  /// A template template parameter pack is a pack expansion if its template
1276243830Sdim  /// parameter list contains an unexpanded parameter pack.
1277243830Sdim  bool isPackExpansion() const {
1278243830Sdim    return ParameterPack &&
1279243830Sdim           getTemplateParameters()->containsUnexpandedParameterPack();
1280243830Sdim  }
1281243830Sdim
1282243830Sdim  /// \brief Whether this parameter is a template template parameter pack that
1283243830Sdim  /// has a known list of different template parameter lists at different
1284243830Sdim  /// positions.
1285243830Sdim  ///
1286243830Sdim  /// A parameter pack is an expanded parameter pack when the original parameter
1287243830Sdim  /// pack's template parameter list was itself a pack expansion, and that
1288243830Sdim  /// expansion has already been expanded. For exampe, given:
1289243830Sdim  ///
1290243830Sdim  /// \code
1291243830Sdim  /// template<typename...Types> struct Outer {
1292243830Sdim  ///   template<template<Types> class...Templates> struct Inner;
1293243830Sdim  /// };
1294243830Sdim  /// \endcode
1295243830Sdim  ///
1296243830Sdim  /// The parameter pack \c Templates is a pack expansion, which expands the
1297243830Sdim  /// pack \c Types. When \c Types is supplied with template arguments by
1298243830Sdim  /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1299243830Sdim  /// parameter pack.
1300243830Sdim  bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1301243830Sdim
1302243830Sdim  /// \brief Retrieves the number of expansion template parameters in
1303243830Sdim  /// an expanded parameter pack.
1304243830Sdim  unsigned getNumExpansionTemplateParameters() const {
1305243830Sdim    assert(ExpandedParameterPack && "Not an expansion parameter pack");
1306243830Sdim    return NumExpandedParams;
1307243830Sdim  }
1308243830Sdim
1309243830Sdim  /// \brief Retrieve a particular expansion type within an expanded parameter
1310243830Sdim  /// pack.
1311243830Sdim  TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
1312243830Sdim    assert(I < NumExpandedParams && "Out-of-range expansion type index");
1313243830Sdim    return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I];
1314243830Sdim  }
1315243830Sdim
1316193326Sed  /// \brief Determine whether this template parameter has a default
1317193326Sed  /// argument.
1318210299Sed  bool hasDefaultArgument() const {
1319210299Sed    return !DefaultArgument.getArgument().isNull();
1320199482Srdivacky  }
1321193326Sed
1322193326Sed  /// \brief Retrieve the default argument, if any.
1323210299Sed  const TemplateArgumentLoc &getDefaultArgument() const {
1324210299Sed    return DefaultArgument;
1325199482Srdivacky  }
1326193326Sed
1327210299Sed  /// \brief Retrieve the location of the default argument, if any.
1328210299Sed  SourceLocation getDefaultArgumentLoc() const;
1329210299Sed
1330210299Sed  /// \brief Determines whether the default argument was inherited
1331210299Sed  /// from a previous declaration of this template.
1332210299Sed  bool defaultArgumentWasInherited() const {
1333210299Sed    return DefaultArgumentWasInherited;
1334210299Sed  }
1335210299Sed
1336210299Sed  /// \brief Set the default argument for this template parameter, and
1337210299Sed  /// whether that default argument was inherited from another
1338210299Sed  /// declaration.
1339210299Sed  void setDefaultArgument(const TemplateArgumentLoc &DefArg, bool Inherited) {
1340193326Sed    DefaultArgument = DefArg;
1341210299Sed    DefaultArgumentWasInherited = Inherited;
1342193326Sed  }
1343193326Sed
1344210299Sed  /// \brief Removes the default argument of this template parameter.
1345210299Sed  void removeDefaultArgument() {
1346210299Sed    DefaultArgument = TemplateArgumentLoc();
1347210299Sed    DefaultArgumentWasInherited = false;
1348210299Sed  }
1349210299Sed
1350234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
1351212904Sdim    SourceLocation End = getLocation();
1352212904Sdim    if (hasDefaultArgument() && !defaultArgumentWasInherited())
1353212904Sdim      End = getDefaultArgument().getSourceRange().getEnd();
1354212904Sdim    return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1355212904Sdim  }
1356212904Sdim
1357193326Sed  // Implement isa/cast/dyncast/etc.
1358203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1359203955Srdivacky  static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1360210299Sed
1361212904Sdim  friend class ASTDeclReader;
1362212904Sdim  friend class ASTDeclWriter;
1363193326Sed};
1364193326Sed
1365193326Sed/// \brief Represents a class template specialization, which refers to
1366193326Sed/// a class template with a given set of template arguments.
1367193326Sed///
1368193326Sed/// Class template specializations represent both explicit
1369193326Sed/// specialization of class templates, as in the example below, and
1370193326Sed/// implicit instantiations of class templates.
1371193326Sed///
1372193326Sed/// \code
1373193326Sed/// template<typename T> class array;
1374198092Srdivacky///
1375198092Srdivacky/// template<>
1376193326Sed/// class array<bool> { }; // class template specialization array<bool>
1377193326Sed/// \endcode
1378198092Srdivackyclass ClassTemplateSpecializationDecl
1379193326Sed  : public CXXRecordDecl, public llvm::FoldingSetNode {
1380198092Srdivacky
1381198092Srdivacky  /// \brief Structure that stores information about a class template
1382198092Srdivacky  /// specialization that was instantiated from a class template partial
1383198092Srdivacky  /// specialization.
1384198092Srdivacky  struct SpecializedPartialSpecialization {
1385198092Srdivacky    /// \brief The class template partial specialization from which this
1386198092Srdivacky    /// class template specialization was instantiated.
1387198092Srdivacky    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1388198092Srdivacky
1389198092Srdivacky    /// \brief The template argument list deduced for the class template
1390198092Srdivacky    /// partial specialization itself.
1391263508Sdim    const TemplateArgumentList *TemplateArgs;
1392198092Srdivacky  };
1393198092Srdivacky
1394193326Sed  /// \brief The template that this specialization specializes
1395198092Srdivacky  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1396198092Srdivacky    SpecializedTemplate;
1397193326Sed
1398210299Sed  /// \brief Further info for explicit template specialization/instantiation.
1399210299Sed  struct ExplicitSpecializationInfo {
1400210299Sed    /// \brief The type-as-written.
1401210299Sed    TypeSourceInfo *TypeAsWritten;
1402210299Sed    /// \brief The location of the extern keyword.
1403210299Sed    SourceLocation ExternLoc;
1404210299Sed    /// \brief The location of the template keyword.
1405210299Sed    SourceLocation TemplateKeywordLoc;
1406210299Sed
1407210299Sed    ExplicitSpecializationInfo()
1408210299Sed      : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
1409210299Sed  };
1410210299Sed
1411210299Sed  /// \brief Further info for explicit template specialization/instantiation.
1412204962Srdivacky  /// Does not apply to implicit specializations.
1413210299Sed  ExplicitSpecializationInfo *ExplicitInfo;
1414204962Srdivacky
1415193326Sed  /// \brief The template arguments used to describe this specialization.
1416263508Sdim  const TemplateArgumentList *TemplateArgs;
1417193326Sed
1418198092Srdivacky  /// \brief The point where this template was instantiated (if any)
1419198092Srdivacky  SourceLocation PointOfInstantiation;
1420198092Srdivacky
1421193326Sed  /// \brief The kind of specialization this declaration refers to.
1422193326Sed  /// Really a value of type TemplateSpecializationKind.
1423198092Srdivacky  unsigned SpecializationKind : 3;
1424193326Sed
1425193326Sedprotected:
1426208600Srdivacky  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
1427221345Sdim                                  DeclContext *DC, SourceLocation StartLoc,
1428221345Sdim                                  SourceLocation IdLoc,
1429193326Sed                                  ClassTemplateDecl *SpecializedTemplate,
1430218893Sdim                                  const TemplateArgument *Args,
1431218893Sdim                                  unsigned NumArgs,
1432198092Srdivacky                                  ClassTemplateSpecializationDecl *PrevDecl);
1433198092Srdivacky
1434210299Sed  explicit ClassTemplateSpecializationDecl(Kind DK);
1435210299Sed
1436193326Sedpublic:
1437193326Sed  static ClassTemplateSpecializationDecl *
1438221345Sdim  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1439221345Sdim         SourceLocation StartLoc, SourceLocation IdLoc,
1440193326Sed         ClassTemplateDecl *SpecializedTemplate,
1441218893Sdim         const TemplateArgument *Args,
1442218893Sdim         unsigned NumArgs,
1443193326Sed         ClassTemplateSpecializationDecl *PrevDecl);
1444210299Sed  static ClassTemplateSpecializationDecl *
1445234353Sdim  CreateDeserialized(ASTContext &C, unsigned ID);
1446193326Sed
1447249423Sdim  virtual void getNameForDiagnostic(raw_ostream &OS,
1448198092Srdivacky                                    const PrintingPolicy &Policy,
1449198092Srdivacky                                    bool Qualified) const;
1450198092Srdivacky
1451234353Sdim  ClassTemplateSpecializationDecl *getMostRecentDecl() {
1452263508Sdim    CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
1453263508Sdim                              this)->getMostRecentDecl();
1454263508Sdim    while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
1455212904Sdim      // FIXME: Does injected class name need to be in the redeclarations chain?
1456234353Sdim      assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
1457234353Sdim      Recent = Recent->getPreviousDecl();
1458212904Sdim    }
1459212904Sdim    return cast<ClassTemplateSpecializationDecl>(Recent);
1460212904Sdim  }
1461212904Sdim
1462193326Sed  /// \brief Retrieve the template that this specialization specializes.
1463198092Srdivacky  ClassTemplateDecl *getSpecializedTemplate() const;
1464193326Sed
1465198092Srdivacky  /// \brief Retrieve the template arguments of the class template
1466198092Srdivacky  /// specialization.
1467198092Srdivacky  const TemplateArgumentList &getTemplateArgs() const {
1468218893Sdim    return *TemplateArgs;
1469193326Sed  }
1470193326Sed
1471193326Sed  /// \brief Determine the kind of specialization that this
1472193326Sed  /// declaration represents.
1473193326Sed  TemplateSpecializationKind getSpecializationKind() const {
1474193326Sed    return static_cast<TemplateSpecializationKind>(SpecializationKind);
1475193326Sed  }
1476193326Sed
1477224145Sdim  bool isExplicitSpecialization() const {
1478224145Sdim    return getSpecializationKind() == TSK_ExplicitSpecialization;
1479224145Sdim  }
1480224145Sdim
1481249423Sdim  /// \brief True if this declaration is an explicit specialization,
1482249423Sdim  /// explicit instantiation declaration, or explicit instantiation
1483249423Sdim  /// definition.
1484249423Sdim  bool isExplicitInstantiationOrSpecialization() const {
1485249423Sdim    switch (getTemplateSpecializationKind()) {
1486249423Sdim    case TSK_ExplicitSpecialization:
1487249423Sdim    case TSK_ExplicitInstantiationDeclaration:
1488249423Sdim    case TSK_ExplicitInstantiationDefinition:
1489249423Sdim      return true;
1490249423Sdim
1491249423Sdim    case TSK_Undeclared:
1492249423Sdim    case TSK_ImplicitInstantiation:
1493249423Sdim      return false;
1494249423Sdim    }
1495249423Sdim    llvm_unreachable("bad template specialization kind");
1496249423Sdim  }
1497249423Sdim
1498193326Sed  void setSpecializationKind(TemplateSpecializationKind TSK) {
1499193326Sed    SpecializationKind = TSK;
1500193326Sed  }
1501193326Sed
1502198092Srdivacky  /// \brief Get the point of instantiation (if any), or null if none.
1503198092Srdivacky  SourceLocation getPointOfInstantiation() const {
1504198092Srdivacky    return PointOfInstantiation;
1505198092Srdivacky  }
1506198092Srdivacky
1507198092Srdivacky  void setPointOfInstantiation(SourceLocation Loc) {
1508198092Srdivacky    assert(Loc.isValid() && "point of instantiation must be valid!");
1509198092Srdivacky    PointOfInstantiation = Loc;
1510198092Srdivacky  }
1511198092Srdivacky
1512198092Srdivacky  /// \brief If this class template specialization is an instantiation of
1513198092Srdivacky  /// a template (rather than an explicit specialization), return the
1514198092Srdivacky  /// class template or class template partial specialization from which it
1515198092Srdivacky  /// was instantiated.
1516198092Srdivacky  llvm::PointerUnion<ClassTemplateDecl *,
1517198092Srdivacky                     ClassTemplatePartialSpecializationDecl *>
1518198092Srdivacky  getInstantiatedFrom() const {
1519198092Srdivacky    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
1520198092Srdivacky        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
1521198092Srdivacky        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
1522212904Sdim      return llvm::PointerUnion<ClassTemplateDecl *,
1523212904Sdim                                ClassTemplatePartialSpecializationDecl *>();
1524198092Srdivacky
1525198092Srdivacky    if (SpecializedPartialSpecialization *PartialSpec
1526198092Srdivacky          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1527198092Srdivacky      return PartialSpec->PartialSpecialization;
1528198092Srdivacky
1529249423Sdim    return SpecializedTemplate.get<ClassTemplateDecl*>();
1530198092Srdivacky  }
1531198092Srdivacky
1532210299Sed  /// \brief Retrieve the class template or class template partial
1533210299Sed  /// specialization which was specialized by this.
1534210299Sed  llvm::PointerUnion<ClassTemplateDecl *,
1535210299Sed                     ClassTemplatePartialSpecializationDecl *>
1536210299Sed  getSpecializedTemplateOrPartial() const {
1537210299Sed    if (SpecializedPartialSpecialization *PartialSpec
1538210299Sed          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1539210299Sed      return PartialSpec->PartialSpecialization;
1540210299Sed
1541249423Sdim    return SpecializedTemplate.get<ClassTemplateDecl*>();
1542210299Sed  }
1543210299Sed
1544198092Srdivacky  /// \brief Retrieve the set of template arguments that should be used
1545198092Srdivacky  /// to instantiate members of the class template or class template partial
1546198092Srdivacky  /// specialization from which this class template specialization was
1547198092Srdivacky  /// instantiated.
1548198092Srdivacky  ///
1549198092Srdivacky  /// \returns For a class template specialization instantiated from the primary
1550198092Srdivacky  /// template, this function will return the same template arguments as
1551198092Srdivacky  /// getTemplateArgs(). For a class template specialization instantiated from
1552198092Srdivacky  /// a class template partial specialization, this function will return the
1553198092Srdivacky  /// deduced template arguments for the class template partial specialization
1554198092Srdivacky  /// itself.
1555198092Srdivacky  const TemplateArgumentList &getTemplateInstantiationArgs() const {
1556198092Srdivacky    if (SpecializedPartialSpecialization *PartialSpec
1557198092Srdivacky        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1558198092Srdivacky      return *PartialSpec->TemplateArgs;
1559198092Srdivacky
1560198092Srdivacky    return getTemplateArgs();
1561198092Srdivacky  }
1562198092Srdivacky
1563198092Srdivacky  /// \brief Note that this class template specialization is actually an
1564198092Srdivacky  /// instantiation of the given class template partial specialization whose
1565198092Srdivacky  /// template arguments have been deduced.
1566198092Srdivacky  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
1567263508Sdim                          const TemplateArgumentList *TemplateArgs) {
1568210299Sed    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
1569210299Sed           "Already set to a class template partial specialization!");
1570198092Srdivacky    SpecializedPartialSpecialization *PS
1571198092Srdivacky      = new (getASTContext()) SpecializedPartialSpecialization();
1572198092Srdivacky    PS->PartialSpecialization = PartialSpec;
1573198092Srdivacky    PS->TemplateArgs = TemplateArgs;
1574198092Srdivacky    SpecializedTemplate = PS;
1575198092Srdivacky  }
1576198092Srdivacky
1577210299Sed  /// \brief Note that this class template specialization is an instantiation
1578210299Sed  /// of the given class template.
1579210299Sed  void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
1580210299Sed    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
1581210299Sed           "Previously set to a class template partial specialization!");
1582210299Sed    SpecializedTemplate = TemplDecl;
1583210299Sed  }
1584210299Sed
1585193326Sed  /// \brief Sets the type of this specialization as it was written by
1586193326Sed  /// the user. This will be a class template specialization type.
1587204962Srdivacky  void setTypeAsWritten(TypeSourceInfo *T) {
1588212904Sdim    if (!ExplicitInfo)
1589212904Sdim      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1590210299Sed    ExplicitInfo->TypeAsWritten = T;
1591193326Sed  }
1592204962Srdivacky  /// \brief Gets the type of this specialization as it was written by
1593204962Srdivacky  /// the user, if it was so written.
1594204962Srdivacky  TypeSourceInfo *getTypeAsWritten() const {
1595210299Sed    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
1596204962Srdivacky  }
1597204962Srdivacky
1598210299Sed  /// \brief Gets the location of the extern keyword, if present.
1599210299Sed  SourceLocation getExternLoc() const {
1600210299Sed    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
1601210299Sed  }
1602210299Sed  /// \brief Sets the location of the extern keyword.
1603210299Sed  void setExternLoc(SourceLocation Loc) {
1604212904Sdim    if (!ExplicitInfo)
1605212904Sdim      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1606210299Sed    ExplicitInfo->ExternLoc = Loc;
1607210299Sed  }
1608210299Sed
1609210299Sed  /// \brief Sets the location of the template keyword.
1610210299Sed  void setTemplateKeywordLoc(SourceLocation Loc) {
1611212904Sdim    if (!ExplicitInfo)
1612212904Sdim      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
1613210299Sed    ExplicitInfo->TemplateKeywordLoc = Loc;
1614210299Sed  }
1615210299Sed  /// \brief Gets the location of the template keyword, if present.
1616210299Sed  SourceLocation getTemplateKeywordLoc() const {
1617210299Sed    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
1618210299Sed  }
1619210299Sed
1620234353Sdim  SourceRange getSourceRange() const LLVM_READONLY;
1621210299Sed
1622193326Sed  void Profile(llvm::FoldingSetNodeID &ID) const {
1623218893Sdim    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
1624193326Sed  }
1625193326Sed
1626198092Srdivacky  static void
1627198092Srdivacky  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
1628198092Srdivacky          unsigned NumTemplateArgs, ASTContext &Context) {
1629194179Sed    ID.AddInteger(NumTemplateArgs);
1630193326Sed    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
1631198092Srdivacky      TemplateArgs[Arg].Profile(ID, Context);
1632193326Sed  }
1633193326Sed
1634203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1635203955Srdivacky  static bool classofKind(Kind K) {
1636210299Sed    return K >= firstClassTemplateSpecialization &&
1637210299Sed           K <= lastClassTemplateSpecialization;
1638193326Sed  }
1639193326Sed
1640218893Sdim  friend class ASTDeclReader;
1641218893Sdim  friend class ASTDeclWriter;
1642193326Sed};
1643193326Sed
1644198092Srdivackyclass ClassTemplatePartialSpecializationDecl
1645198092Srdivacky  : public ClassTemplateSpecializationDecl {
1646234353Sdim  virtual void anchor();
1647234353Sdim
1648198092Srdivacky  /// \brief The list of template parameters
1649193326Sed  TemplateParameterList* TemplateParams;
1650193326Sed
1651198893Srdivacky  /// \brief The source info for the template arguments as written.
1652204962Srdivacky  /// FIXME: redundant with TypeAsWritten?
1653263508Sdim  const ASTTemplateArgumentListInfo *ArgsAsWritten;
1654198893Srdivacky
1655234353Sdim  /// \brief The class template partial specialization from which this
1656198893Srdivacky  /// class template partial specialization was instantiated.
1657198893Srdivacky  ///
1658198893Srdivacky  /// The boolean value will be true to indicate that this class template
1659198893Srdivacky  /// partial specialization was specialized at this level.
1660198893Srdivacky  llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
1661198893Srdivacky      InstantiatedFromMember;
1662234353Sdim
1663208600Srdivacky  ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1664221345Sdim                                         DeclContext *DC,
1665221345Sdim                                         SourceLocation StartLoc,
1666221345Sdim                                         SourceLocation IdLoc,
1667193326Sed                                         TemplateParameterList *Params,
1668193326Sed                                         ClassTemplateDecl *SpecializedTemplate,
1669218893Sdim                                         const TemplateArgument *Args,
1670218893Sdim                                         unsigned NumArgs,
1671263508Sdim                               const ASTTemplateArgumentListInfo *ArgsAsWritten,
1672263508Sdim                               ClassTemplatePartialSpecializationDecl *PrevDecl);
1673234353Sdim
1674210299Sed  ClassTemplatePartialSpecializationDecl()
1675210299Sed    : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
1676263508Sdim      TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { }
1677193326Sed
1678193326Sedpublic:
1679193326Sed  static ClassTemplatePartialSpecializationDecl *
1680234353Sdim  Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1681221345Sdim         SourceLocation StartLoc, SourceLocation IdLoc,
1682193326Sed         TemplateParameterList *Params,
1683193326Sed         ClassTemplateDecl *SpecializedTemplate,
1684218893Sdim         const TemplateArgument *Args,
1685218893Sdim         unsigned NumArgs,
1686199990Srdivacky         const TemplateArgumentListInfo &ArgInfos,
1687204962Srdivacky         QualType CanonInjectedType,
1688263508Sdim         ClassTemplatePartialSpecializationDecl *PrevDecl);
1689193326Sed
1690210299Sed  static ClassTemplatePartialSpecializationDecl *
1691234353Sdim  CreateDeserialized(ASTContext &C, unsigned ID);
1692210299Sed
1693234353Sdim  ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
1694212904Sdim    return cast<ClassTemplatePartialSpecializationDecl>(
1695263508Sdim             static_cast<ClassTemplateSpecializationDecl *>(
1696263508Sdim               this)->getMostRecentDecl());
1697212904Sdim  }
1698212904Sdim
1699193326Sed  /// Get the list of template parameters
1700193326Sed  TemplateParameterList *getTemplateParameters() const {
1701193326Sed    return TemplateParams;
1702193326Sed  }
1703193326Sed
1704198893Srdivacky  /// Get the template arguments as written.
1705263508Sdim  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
1706198893Srdivacky    return ArgsAsWritten;
1707198893Srdivacky  }
1708198893Srdivacky
1709198893Srdivacky  /// \brief Retrieve the member class template partial specialization from
1710198893Srdivacky  /// which this particular class template partial specialization was
1711198893Srdivacky  /// instantiated.
1712198893Srdivacky  ///
1713198893Srdivacky  /// \code
1714198893Srdivacky  /// template<typename T>
1715198893Srdivacky  /// struct Outer {
1716198893Srdivacky  ///   template<typename U> struct Inner;
1717198893Srdivacky  ///   template<typename U> struct Inner<U*> { }; // #1
1718198893Srdivacky  /// };
1719198893Srdivacky  ///
1720198893Srdivacky  /// Outer<float>::Inner<int*> ii;
1721198893Srdivacky  /// \endcode
1722198893Srdivacky  ///
1723198893Srdivacky  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
1724234353Sdim  /// end up instantiating the partial specialization
1725234353Sdim  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
1726234353Sdim  /// template partial specialization \c Outer<T>::Inner<U*>. Given
1727198893Srdivacky  /// \c Outer<float>::Inner<U*>, this function would return
1728198893Srdivacky  /// \c Outer<T>::Inner<U*>.
1729198893Srdivacky  ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
1730263508Sdim    ClassTemplatePartialSpecializationDecl *First =
1731263508Sdim        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1732198893Srdivacky    return First->InstantiatedFromMember.getPointer();
1733198893Srdivacky  }
1734234353Sdim
1735198893Srdivacky  void setInstantiatedFromMember(
1736198893Srdivacky                          ClassTemplatePartialSpecializationDecl *PartialSpec) {
1737263508Sdim    ClassTemplatePartialSpecializationDecl *First =
1738263508Sdim        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1739198893Srdivacky    First->InstantiatedFromMember.setPointer(PartialSpec);
1740198893Srdivacky  }
1741234353Sdim
1742234353Sdim  /// \brief Determines whether this class template partial specialization
1743198893Srdivacky  /// template was a specialization of a member partial specialization.
1744198893Srdivacky  ///
1745198893Srdivacky  /// In the following example, the member template partial specialization
1746198893Srdivacky  /// \c X<int>::Inner<T*> is a member specialization.
1747198893Srdivacky  ///
1748198893Srdivacky  /// \code
1749198893Srdivacky  /// template<typename T>
1750198893Srdivacky  /// struct X {
1751198893Srdivacky  ///   template<typename U> struct Inner;
1752198893Srdivacky  ///   template<typename U> struct Inner<U*>;
1753198893Srdivacky  /// };
1754198893Srdivacky  ///
1755198893Srdivacky  /// template<> template<typename T>
1756198893Srdivacky  /// struct X<int>::Inner<T*> { /* ... */ };
1757198893Srdivacky  /// \endcode
1758198893Srdivacky  bool isMemberSpecialization() {
1759263508Sdim    ClassTemplatePartialSpecializationDecl *First =
1760263508Sdim        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1761198893Srdivacky    return First->InstantiatedFromMember.getInt();
1762198893Srdivacky  }
1763234353Sdim
1764198893Srdivacky  /// \brief Note that this member template is a specialization.
1765198893Srdivacky  void setMemberSpecialization() {
1766263508Sdim    ClassTemplatePartialSpecializationDecl *First =
1767263508Sdim        cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
1768198893Srdivacky    assert(First->InstantiatedFromMember.getPointer() &&
1769198893Srdivacky           "Only member templates can be member template specializations");
1770198893Srdivacky    return First->InstantiatedFromMember.setInt(true);
1771198893Srdivacky  }
1772207619Srdivacky
1773207619Srdivacky  /// Retrieves the injected specialization type for this partial
1774207619Srdivacky  /// specialization.  This is not the same as the type-decl-type for
1775207619Srdivacky  /// this partial specialization, which is an InjectedClassNameType.
1776207619Srdivacky  QualType getInjectedSpecializationType() const {
1777207619Srdivacky    assert(getTypeForDecl() && "partial specialization has no type set!");
1778207619Srdivacky    return cast<InjectedClassNameType>(getTypeForDecl())
1779207619Srdivacky             ->getInjectedSpecializationType();
1780207619Srdivacky  }
1781234353Sdim
1782193326Sed  // FIXME: Add Profile support!
1783193326Sed
1784203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1785203955Srdivacky  static bool classofKind(Kind K) {
1786203955Srdivacky    return K == ClassTemplatePartialSpecialization;
1787193326Sed  }
1788193326Sed
1789218893Sdim  friend class ASTDeclReader;
1790218893Sdim  friend class ASTDeclWriter;
1791193326Sed};
1792193326Sed
1793193326Sed/// Declaration of a class template.
1794234353Sdimclass ClassTemplateDecl : public RedeclarableTemplateDecl {
1795208600Srdivacky  static void DeallocateCommon(void *Ptr);
1796234353Sdim
1797193326Sedprotected:
1798193326Sed  /// \brief Data that is common to all of the declarations of a given
1799193326Sed  /// class template.
1800212904Sdim  struct Common : CommonBase {
1801218893Sdim    Common() : LazySpecializations() { }
1802234353Sdim
1803193326Sed    /// \brief The class template specializations for this class
1804193326Sed    /// template, including explicit specializations and instantiations.
1805239462Sdim    llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
1806193326Sed
1807193326Sed    /// \brief The class template partial specializations for this class
1808193326Sed    /// template.
1809239462Sdim    llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
1810193326Sed      PartialSpecializations;
1811193326Sed
1812193326Sed    /// \brief The injected-class-name type for this class template.
1813193326Sed    QualType InjectedClassNameType;
1814234353Sdim
1815218893Sdim    /// \brief If non-null, points to an array of specializations (including
1816263508Sdim    /// partial specializations) known only by their external declaration IDs.
1817218893Sdim    ///
1818218893Sdim    /// The first value in the array is the number of of specializations/
1819218893Sdim    /// partial specializations that follow.
1820218893Sdim    uint32_t *LazySpecializations;
1821193326Sed  };
1822193326Sed
1823218893Sdim  /// \brief Load any lazily-loaded specializations from the external source.
1824249423Sdim  void LoadLazySpecializations() const;
1825234353Sdim
1826212904Sdim  /// \brief Retrieve the set of specializations of this class template.
1827249423Sdim  llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
1828249423Sdim  getSpecializations() const;
1829193326Sed
1830212904Sdim  /// \brief Retrieve the set of partial specializations of this class
1831212904Sdim  /// template.
1832239462Sdim  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
1833218893Sdim  getPartialSpecializations();
1834198092Srdivacky
1835193326Sed  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
1836210299Sed                    TemplateParameterList *Params, NamedDecl *Decl)
1837212904Sdim    : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
1838193326Sed
1839221345Sdim  ClassTemplateDecl(EmptyShell Empty)
1840221345Sdim    : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
1841221345Sdim                               DeclarationName(), 0, 0) { }
1842221345Sdim
1843249423Sdim  CommonBase *newCommon(ASTContext &C) const;
1844212904Sdim
1845249423Sdim  Common *getCommonPtr() const {
1846212904Sdim    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
1847212904Sdim  }
1848212904Sdim
1849193326Sedpublic:
1850239462Sdim  /// \brief Get the underlying class declarations of the template.
1851193326Sed  CXXRecordDecl *getTemplatedDecl() const {
1852193326Sed    return static_cast<CXXRecordDecl *>(TemplatedDecl);
1853193326Sed  }
1854193326Sed
1855239462Sdim  /// \brief Returns whether this template declaration defines the primary
1856212904Sdim  /// class pattern.
1857212904Sdim  bool isThisDeclarationADefinition() const {
1858212904Sdim    return getTemplatedDecl()->isThisDeclarationADefinition();
1859193326Sed  }
1860193326Sed
1861239462Sdim  /// \brief Create a class template node.
1862212904Sdim  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
1863212904Sdim                                   SourceLocation L,
1864212904Sdim                                   DeclarationName Name,
1865212904Sdim                                   TemplateParameterList *Params,
1866212904Sdim                                   NamedDecl *Decl,
1867212904Sdim                                   ClassTemplateDecl *PrevDecl);
1868212904Sdim
1869239462Sdim  /// \brief Create an empty class template node.
1870234353Sdim  static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1871221345Sdim
1872212904Sdim  /// \brief Return the specialization with the provided arguments if it exists,
1873212904Sdim  /// otherwise return the insertion point.
1874212904Sdim  ClassTemplateSpecializationDecl *
1875212904Sdim  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1876212904Sdim                     void *&InsertPos);
1877212904Sdim
1878212904Sdim  /// \brief Insert the specified specialization knowing that it is not already
1879212904Sdim  /// in. InsertPos must be obtained from findSpecialization.
1880218893Sdim  void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
1881212904Sdim
1882212904Sdim  ClassTemplateDecl *getCanonicalDecl() {
1883234353Sdim    return cast<ClassTemplateDecl>(
1884234353Sdim             RedeclarableTemplateDecl::getCanonicalDecl());
1885212904Sdim  }
1886212904Sdim  const ClassTemplateDecl *getCanonicalDecl() const {
1887234353Sdim    return cast<ClassTemplateDecl>(
1888234353Sdim             RedeclarableTemplateDecl::getCanonicalDecl());
1889212904Sdim  }
1890212904Sdim
1891212904Sdim  /// \brief Retrieve the previous declaration of this class template, or
1892210299Sed  /// NULL if no such declaration exists.
1893234353Sdim  ClassTemplateDecl *getPreviousDecl() {
1894234353Sdim    return cast_or_null<ClassTemplateDecl>(
1895263508Sdim             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1896210299Sed  }
1897210299Sed
1898212904Sdim  /// \brief Retrieve the previous declaration of this class template, or
1899212904Sdim  /// NULL if no such declaration exists.
1900234353Sdim  const ClassTemplateDecl *getPreviousDecl() const {
1901234353Sdim    return cast_or_null<ClassTemplateDecl>(
1902263508Sdim             static_cast<const RedeclarableTemplateDecl *>(
1903263508Sdim               this)->getPreviousDecl());
1904210299Sed  }
1905210299Sed
1906263508Sdim  ClassTemplateDecl *getMostRecentDecl() {
1907263508Sdim    return cast<ClassTemplateDecl>(
1908263508Sdim        static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
1909263508Sdim  }
1910263508Sdim  const ClassTemplateDecl *getMostRecentDecl() const {
1911263508Sdim    return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
1912263508Sdim  }
1913263508Sdim
1914212904Sdim  ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
1915234353Sdim    return cast_or_null<ClassTemplateDecl>(
1916234353Sdim             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
1917210299Sed  }
1918210299Sed
1919212904Sdim  /// \brief Return the partial specialization with the provided arguments if it
1920212904Sdim  /// exists, otherwise return the insertion point.
1921212904Sdim  ClassTemplatePartialSpecializationDecl *
1922212904Sdim  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
1923212904Sdim                            void *&InsertPos);
1924193326Sed
1925212904Sdim  /// \brief Insert the specified partial specialization knowing that it is not
1926212904Sdim  /// already in. InsertPos must be obtained from findPartialSpecialization.
1927212904Sdim  void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
1928218893Sdim                                void *InsertPos);
1929193326Sed
1930207619Srdivacky  /// \brief Retrieve the partial specializations as an ordered list.
1931207619Srdivacky  void getPartialSpecializations(
1932226633Sdim          SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
1933234353Sdim
1934198092Srdivacky  /// \brief Find a class template partial specialization with the given
1935198092Srdivacky  /// type T.
1936198092Srdivacky  ///
1937212904Sdim  /// \param T a dependent type that names a specialization of this class
1938198092Srdivacky  /// template.
1939198092Srdivacky  ///
1940198092Srdivacky  /// \returns the class template partial specialization that exactly matches
1941198092Srdivacky  /// the type \p T, or NULL if no such partial specialization exists.
1942198092Srdivacky  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
1943234353Sdim
1944212904Sdim  /// \brief Find a class template partial specialization which was instantiated
1945212904Sdim  /// from the given member partial specialization.
1946212904Sdim  ///
1947212904Sdim  /// \param D a member class template partial specialization.
1948212904Sdim  ///
1949212904Sdim  /// \returns the class template partial specialization which was instantiated
1950212904Sdim  /// from the given member partial specialization, or NULL if no such partial
1951212904Sdim  /// specialization exists.
1952212904Sdim  ClassTemplatePartialSpecializationDecl *
1953212904Sdim  findPartialSpecInstantiatedFromMember(
1954212904Sdim                                     ClassTemplatePartialSpecializationDecl *D);
1955198092Srdivacky
1956204962Srdivacky  /// \brief Retrieve the template specialization type of the
1957204962Srdivacky  /// injected-class-name for this class template.
1958193326Sed  ///
1959193326Sed  /// The injected-class-name for a class template \c X is \c
1960193326Sed  /// X<template-args>, where \c template-args is formed from the
1961193326Sed  /// template arguments that correspond to the template parameters of
1962193326Sed  /// \c X. For example:
1963193326Sed  ///
1964193326Sed  /// \code
1965193326Sed  /// template<typename T, int N>
1966193326Sed  /// struct array {
1967193326Sed  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
1968193326Sed  /// };
1969193326Sed  /// \endcode
1970210299Sed  QualType getInjectedClassNameSpecialization();
1971193326Sed
1972212904Sdim  typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
1973212904Sdim
1974249423Sdim  spec_iterator spec_begin() const {
1975212904Sdim    return makeSpecIterator(getSpecializations(), false);
1976198092Srdivacky  }
1977198092Srdivacky
1978249423Sdim  spec_iterator spec_end() const {
1979212904Sdim    return makeSpecIterator(getSpecializations(), true);
1980198092Srdivacky  }
1981198092Srdivacky
1982212904Sdim  typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
1983212904Sdim          partial_spec_iterator;
1984212904Sdim
1985212904Sdim  partial_spec_iterator partial_spec_begin() {
1986212904Sdim    return makeSpecIterator(getPartialSpecializations(), false);
1987198092Srdivacky  }
1988212904Sdim
1989212904Sdim  partial_spec_iterator partial_spec_end() {
1990212904Sdim    return makeSpecIterator(getPartialSpecializations(), true);
1991198092Srdivacky  }
1992212904Sdim
1993193326Sed  // Implement isa/cast/dyncast support
1994203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1995203955Srdivacky  static bool classofKind(Kind K) { return K == ClassTemplate; }
1996193326Sed
1997212904Sdim  friend class ASTDeclReader;
1998212904Sdim  friend class ASTDeclWriter;
1999193326Sed};
2000193326Sed
2001239462Sdim/// \brief Declaration of a friend template.
2002198092Srdivacky///
2003239462Sdim/// For example:
2004239462Sdim/// \code
2005239462Sdim/// template \<typename T> class A {
2006198092Srdivacky///   friend class MyVector<T>; // not a friend template
2007239462Sdim///   template \<typename U> friend class B; // not a friend template
2008239462Sdim///   template \<typename U> friend class Foo<T>::Nested; // friend template
2009212904Sdim/// };
2010239462Sdim/// \endcode
2011239462Sdim///
2012239462Sdim/// \note This class is not currently in use.  All of the above
2013212904Sdim/// will yield a FriendDecl, not a FriendTemplateDecl.
2014198092Srdivackyclass FriendTemplateDecl : public Decl {
2015234353Sdim  virtual void anchor();
2016198092Srdivackypublic:
2017206084Srdivacky  typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
2018198092Srdivacky
2019198092Srdivackyprivate:
2020198092Srdivacky  // The number of template parameters;  always non-zero.
2021198092Srdivacky  unsigned NumParams;
2022198092Srdivacky
2023198092Srdivacky  // The parameter list.
2024198092Srdivacky  TemplateParameterList **Params;
2025198092Srdivacky
2026198092Srdivacky  // The declaration that's a friend of this class.
2027198092Srdivacky  FriendUnion Friend;
2028198092Srdivacky
2029198092Srdivacky  // Location of the 'friend' specifier.
2030198092Srdivacky  SourceLocation FriendLoc;
2031198092Srdivacky
2032198092Srdivacky
2033198092Srdivacky  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
2034234353Sdim                     unsigned NParams,
2035198092Srdivacky                     TemplateParameterList **Params,
2036198092Srdivacky                     FriendUnion Friend,
2037198092Srdivacky                     SourceLocation FriendLoc)
2038198092Srdivacky    : Decl(Decl::FriendTemplate, DC, Loc),
2039198092Srdivacky      NumParams(NParams),
2040198092Srdivacky      Params(Params),
2041198092Srdivacky      Friend(Friend),
2042198092Srdivacky      FriendLoc(FriendLoc)
2043198092Srdivacky  {}
2044198092Srdivacky
2045212904Sdim  FriendTemplateDecl(EmptyShell Empty)
2046212904Sdim    : Decl(Decl::FriendTemplate, Empty),
2047212904Sdim      NumParams(0),
2048212904Sdim      Params(0)
2049212904Sdim  {}
2050212904Sdim
2051198092Srdivackypublic:
2052198092Srdivacky  static FriendTemplateDecl *Create(ASTContext &Context,
2053198092Srdivacky                                    DeclContext *DC, SourceLocation Loc,
2054234353Sdim                                    unsigned NParams,
2055198092Srdivacky                                    TemplateParameterList **Params,
2056198092Srdivacky                                    FriendUnion Friend,
2057198092Srdivacky                                    SourceLocation FriendLoc);
2058198092Srdivacky
2059234353Sdim  static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2060212904Sdim
2061198092Srdivacky  /// If this friend declaration names a templated type (or
2062198092Srdivacky  /// a dependent member type of a templated type), return that
2063198092Srdivacky  /// type;  otherwise return null.
2064206084Srdivacky  TypeSourceInfo *getFriendType() const {
2065206084Srdivacky    return Friend.dyn_cast<TypeSourceInfo*>();
2066198092Srdivacky  }
2067198092Srdivacky
2068198092Srdivacky  /// If this friend declaration names a templated function (or
2069198092Srdivacky  /// a member function of a templated type), return that type;
2070198092Srdivacky  /// otherwise return null.
2071198092Srdivacky  NamedDecl *getFriendDecl() const {
2072198092Srdivacky    return Friend.dyn_cast<NamedDecl*>();
2073198092Srdivacky  }
2074198092Srdivacky
2075239462Sdim  /// \brief Retrieves the location of the 'friend' keyword.
2076198092Srdivacky  SourceLocation getFriendLoc() const {
2077198092Srdivacky    return FriendLoc;
2078198092Srdivacky  }
2079198092Srdivacky
2080198092Srdivacky  TemplateParameterList *getTemplateParameterList(unsigned i) const {
2081198092Srdivacky    assert(i <= NumParams);
2082198092Srdivacky    return Params[i];
2083198092Srdivacky  }
2084198092Srdivacky
2085198092Srdivacky  unsigned getNumTemplateParameters() const {
2086198092Srdivacky    return NumParams;
2087198092Srdivacky  }
2088198092Srdivacky
2089198092Srdivacky  // Implement isa/cast/dyncast/etc.
2090203955Srdivacky  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2091203955Srdivacky  static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2092212904Sdim
2093212904Sdim  friend class ASTDeclReader;
2094198092Srdivacky};
2095198092Srdivacky
2096239462Sdim/// \brief Declaration of an alias template.
2097223017Sdim///
2098239462Sdim/// For example:
2099239462Sdim/// \code
2100239462Sdim/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
2101239462Sdim/// \endcode
2102234353Sdimclass TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
2103223017Sdim  static void DeallocateCommon(void *Ptr);
2104223017Sdim
2105223017Sdimprotected:
2106223017Sdim  typedef CommonBase Common;
2107223017Sdim
2108223017Sdim  TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
2109223017Sdim                        TemplateParameterList *Params, NamedDecl *Decl)
2110223017Sdim    : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
2111223017Sdim
2112249423Sdim  CommonBase *newCommon(ASTContext &C) const;
2113223017Sdim
2114223017Sdim  Common *getCommonPtr() {
2115223017Sdim    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2116223017Sdim  }
2117223017Sdim
2118223017Sdimpublic:
2119223017Sdim  /// Get the underlying function declaration of the template.
2120223017Sdim  TypeAliasDecl *getTemplatedDecl() const {
2121223017Sdim    return static_cast<TypeAliasDecl*>(TemplatedDecl);
2122223017Sdim  }
2123223017Sdim
2124223017Sdim
2125223017Sdim  TypeAliasTemplateDecl *getCanonicalDecl() {
2126234353Sdim    return cast<TypeAliasTemplateDecl>(
2127234353Sdim             RedeclarableTemplateDecl::getCanonicalDecl());
2128223017Sdim  }
2129223017Sdim  const TypeAliasTemplateDecl *getCanonicalDecl() const {
2130234353Sdim    return cast<TypeAliasTemplateDecl>(
2131234353Sdim             RedeclarableTemplateDecl::getCanonicalDecl());
2132223017Sdim  }
2133223017Sdim
2134223017Sdim  /// \brief Retrieve the previous declaration of this function template, or
2135223017Sdim  /// NULL if no such declaration exists.
2136234353Sdim  TypeAliasTemplateDecl *getPreviousDecl() {
2137234353Sdim    return cast_or_null<TypeAliasTemplateDecl>(
2138263508Sdim             static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2139223017Sdim  }
2140223017Sdim
2141223017Sdim  /// \brief Retrieve the previous declaration of this function template, or
2142223017Sdim  /// NULL if no such declaration exists.
2143234353Sdim  const TypeAliasTemplateDecl *getPreviousDecl() const {
2144234353Sdim    return cast_or_null<TypeAliasTemplateDecl>(
2145263508Sdim             static_cast<const RedeclarableTemplateDecl *>(
2146263508Sdim               this)->getPreviousDecl());
2147223017Sdim  }
2148223017Sdim
2149223017Sdim  TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
2150234353Sdim    return cast_or_null<TypeAliasTemplateDecl>(
2151234353Sdim             RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
2152223017Sdim  }
2153223017Sdim
2154234353Sdim
2155223017Sdim  /// \brief Create a function template node.
2156223017Sdim  static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
2157223017Sdim                                       SourceLocation L,
2158223017Sdim                                       DeclarationName Name,
2159223017Sdim                                       TemplateParameterList *Params,
2160223017Sdim                                       NamedDecl *Decl);
2161223017Sdim
2162223017Sdim  /// \brief Create an empty alias template node.
2163234353Sdim  static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2164223017Sdim
2165223017Sdim  // Implement isa/cast/dyncast support
2166223017Sdim  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2167223017Sdim  static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2168223017Sdim
2169223017Sdim  friend class ASTDeclReader;
2170223017Sdim  friend class ASTDeclWriter;
2171223017Sdim};
2172223017Sdim
2173239462Sdim/// \brief Declaration of a function specialization at template class scope.
2174239462Sdim///
2175226633Sdim/// This is a non standard extension needed to support MSVC.
2176239462Sdim///
2177226633Sdim/// For example:
2178239462Sdim/// \code
2179226633Sdim/// template <class T>
2180226633Sdim/// class A {
2181226633Sdim///    template <class U> void foo(U a) { }
2182226633Sdim///    template<> void foo(int a) { }
2183226633Sdim/// }
2184239462Sdim/// \endcode
2185226633Sdim///
2186226633Sdim/// "template<> foo(int a)" will be saved in Specialization as a normal
2187226633Sdim/// CXXMethodDecl. Then during an instantiation of class A, it will be
2188226633Sdim/// transformed into an actual function specialization.
2189226633Sdimclass ClassScopeFunctionSpecializationDecl : public Decl {
2190234353Sdim  virtual void anchor();
2191234353Sdim
2192226633Sdim  ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
2193239462Sdim                                       CXXMethodDecl *FD, bool Args,
2194239462Sdim                                       TemplateArgumentListInfo TemplArgs)
2195226633Sdim    : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
2196239462Sdim      Specialization(FD), HasExplicitTemplateArgs(Args),
2197239462Sdim      TemplateArgs(TemplArgs) {}
2198226633Sdim
2199226633Sdim  ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
2200226633Sdim    : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
2201226633Sdim
2202226633Sdim  CXXMethodDecl *Specialization;
2203239462Sdim  bool HasExplicitTemplateArgs;
2204239462Sdim  TemplateArgumentListInfo TemplateArgs;
2205226633Sdim
2206226633Sdimpublic:
2207226633Sdim  CXXMethodDecl *getSpecialization() const { return Specialization; }
2208239462Sdim  bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
2209239462Sdim  const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
2210226633Sdim
2211226633Sdim  static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
2212226633Sdim                                                      DeclContext *DC,
2213226633Sdim                                                      SourceLocation Loc,
2214239462Sdim                                                      CXXMethodDecl *FD,
2215239462Sdim                                                   bool HasExplicitTemplateArgs,
2216239462Sdim                                        TemplateArgumentListInfo TemplateArgs) {
2217239462Sdim    return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD,
2218239462Sdim                                                        HasExplicitTemplateArgs,
2219239462Sdim                                                        TemplateArgs);
2220226633Sdim  }
2221226633Sdim
2222234353Sdim  static ClassScopeFunctionSpecializationDecl *
2223234353Sdim  CreateDeserialized(ASTContext &Context, unsigned ID);
2224234353Sdim
2225226633Sdim  // Implement isa/cast/dyncast/etc.
2226226633Sdim  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2227226633Sdim  static bool classofKind(Kind K) {
2228226633Sdim    return K == Decl::ClassScopeFunctionSpecialization;
2229226633Sdim  }
2230226633Sdim
2231226633Sdim  friend class ASTDeclReader;
2232226633Sdim  friend class ASTDeclWriter;
2233226633Sdim};
2234226633Sdim
2235195099Sed/// Implementation of inline functions that require the template declarations
2236198092Srdivackyinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
2237195099Sed  : Function(FTD) { }
2238195099Sed
2239263508Sdim/// \brief Represents a variable template specialization, which refers to
2240263508Sdim/// a variable template with a given set of template arguments.
2241263508Sdim///
2242263508Sdim/// Variable template specializations represent both explicit
2243263508Sdim/// specializations of variable templates, as in the example below, and
2244263508Sdim/// implicit instantiations of variable templates.
2245263508Sdim///
2246263508Sdim/// \code
2247263508Sdim/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2248263508Sdim///
2249263508Sdim/// template<>
2250263508Sdim/// constexpr float pi<float>; // variable template specialization pi<float>
2251263508Sdim/// \endcode
2252263508Sdimclass VarTemplateSpecializationDecl : public VarDecl,
2253263508Sdim                                      public llvm::FoldingSetNode {
2254263508Sdim
2255263508Sdim  /// \brief Structure that stores information about a variable template
2256263508Sdim  /// specialization that was instantiated from a variable template partial
2257263508Sdim  /// specialization.
2258263508Sdim  struct SpecializedPartialSpecialization {
2259263508Sdim    /// \brief The variable template partial specialization from which this
2260263508Sdim    /// variable template specialization was instantiated.
2261263508Sdim    VarTemplatePartialSpecializationDecl *PartialSpecialization;
2262263508Sdim
2263263508Sdim    /// \brief The template argument list deduced for the variable template
2264263508Sdim    /// partial specialization itself.
2265263508Sdim    const TemplateArgumentList *TemplateArgs;
2266263508Sdim  };
2267263508Sdim
2268263508Sdim  /// \brief The template that this specialization specializes.
2269263508Sdim  llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2270263508Sdim  SpecializedTemplate;
2271263508Sdim
2272263508Sdim  /// \brief Further info for explicit template specialization/instantiation.
2273263508Sdim  struct ExplicitSpecializationInfo {
2274263508Sdim    /// \brief The type-as-written.
2275263508Sdim    TypeSourceInfo *TypeAsWritten;
2276263508Sdim    /// \brief The location of the extern keyword.
2277263508Sdim    SourceLocation ExternLoc;
2278263508Sdim    /// \brief The location of the template keyword.
2279263508Sdim    SourceLocation TemplateKeywordLoc;
2280263508Sdim
2281263508Sdim    ExplicitSpecializationInfo()
2282263508Sdim        : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
2283263508Sdim  };
2284263508Sdim
2285263508Sdim  /// \brief Further info for explicit template specialization/instantiation.
2286263508Sdim  /// Does not apply to implicit specializations.
2287263508Sdim  ExplicitSpecializationInfo *ExplicitInfo;
2288263508Sdim
2289263508Sdim  /// \brief The template arguments used to describe this specialization.
2290263508Sdim  const TemplateArgumentList *TemplateArgs;
2291263508Sdim  TemplateArgumentListInfo TemplateArgsInfo;
2292263508Sdim
2293263508Sdim  /// \brief The point where this template was instantiated (if any).
2294263508Sdim  SourceLocation PointOfInstantiation;
2295263508Sdim
2296263508Sdim  /// \brief The kind of specialization this declaration refers to.
2297263508Sdim  /// Really a value of type TemplateSpecializationKind.
2298263508Sdim  unsigned SpecializationKind : 3;
2299263508Sdim
2300263508Sdimprotected:
2301263508Sdim  VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC,
2302263508Sdim                                SourceLocation StartLoc, SourceLocation IdLoc,
2303263508Sdim                                VarTemplateDecl *SpecializedTemplate,
2304263508Sdim                                QualType T, TypeSourceInfo *TInfo,
2305263508Sdim                                StorageClass S, const TemplateArgument *Args,
2306263508Sdim                                unsigned NumArgs);
2307263508Sdim
2308263508Sdim  explicit VarTemplateSpecializationDecl(Kind DK);
2309263508Sdim
2310263508Sdimpublic:
2311263508Sdim  static VarTemplateSpecializationDecl *
2312263508Sdim  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2313263508Sdim         SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2314263508Sdim         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
2315263508Sdim         unsigned NumArgs);
2316263508Sdim  static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
2317263508Sdim                                                           unsigned ID);
2318263508Sdim
2319263508Sdim  virtual void getNameForDiagnostic(raw_ostream &OS,
2320263508Sdim                                    const PrintingPolicy &Policy,
2321263508Sdim                                    bool Qualified) const;
2322263508Sdim
2323263508Sdim  VarTemplateSpecializationDecl *getMostRecentDecl() {
2324263508Sdim    VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2325263508Sdim    return cast<VarTemplateSpecializationDecl>(Recent);
2326263508Sdim  }
2327263508Sdim
2328263508Sdim  /// \brief Retrieve the template that this specialization specializes.
2329263508Sdim  VarTemplateDecl *getSpecializedTemplate() const;
2330263508Sdim
2331263508Sdim  /// \brief Retrieve the template arguments of the variable template
2332263508Sdim  /// specialization.
2333263508Sdim  const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2334263508Sdim
2335263508Sdim  // TODO: Always set this when creating the new specialization?
2336263508Sdim  void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
2337263508Sdim
2338263508Sdim  const TemplateArgumentListInfo &getTemplateArgsInfo() const {
2339263508Sdim    return TemplateArgsInfo;
2340263508Sdim  }
2341263508Sdim
2342263508Sdim  /// \brief Determine the kind of specialization that this
2343263508Sdim  /// declaration represents.
2344263508Sdim  TemplateSpecializationKind getSpecializationKind() const {
2345263508Sdim    return static_cast<TemplateSpecializationKind>(SpecializationKind);
2346263508Sdim  }
2347263508Sdim
2348263508Sdim  bool isExplicitSpecialization() const {
2349263508Sdim    return getSpecializationKind() == TSK_ExplicitSpecialization;
2350263508Sdim  }
2351263508Sdim
2352263508Sdim  /// \brief True if this declaration is an explicit specialization,
2353263508Sdim  /// explicit instantiation declaration, or explicit instantiation
2354263508Sdim  /// definition.
2355263508Sdim  bool isExplicitInstantiationOrSpecialization() const {
2356263508Sdim    switch (getTemplateSpecializationKind()) {
2357263508Sdim    case TSK_ExplicitSpecialization:
2358263508Sdim    case TSK_ExplicitInstantiationDeclaration:
2359263508Sdim    case TSK_ExplicitInstantiationDefinition:
2360263508Sdim      return true;
2361263508Sdim
2362263508Sdim    case TSK_Undeclared:
2363263508Sdim    case TSK_ImplicitInstantiation:
2364263508Sdim      return false;
2365263508Sdim    }
2366263508Sdim    llvm_unreachable("bad template specialization kind");
2367263508Sdim  }
2368263508Sdim
2369263508Sdim  void setSpecializationKind(TemplateSpecializationKind TSK) {
2370263508Sdim    SpecializationKind = TSK;
2371263508Sdim  }
2372263508Sdim
2373263508Sdim  /// \brief Get the point of instantiation (if any), or null if none.
2374263508Sdim  SourceLocation getPointOfInstantiation() const {
2375263508Sdim    return PointOfInstantiation;
2376263508Sdim  }
2377263508Sdim
2378263508Sdim  void setPointOfInstantiation(SourceLocation Loc) {
2379263508Sdim    assert(Loc.isValid() && "point of instantiation must be valid!");
2380263508Sdim    PointOfInstantiation = Loc;
2381263508Sdim  }
2382263508Sdim
2383263508Sdim  /// \brief If this variable template specialization is an instantiation of
2384263508Sdim  /// a template (rather than an explicit specialization), return the
2385263508Sdim  /// variable template or variable template partial specialization from which
2386263508Sdim  /// it was instantiated.
2387263508Sdim  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2388263508Sdim  getInstantiatedFrom() const {
2389263508Sdim    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
2390263508Sdim        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
2391263508Sdim        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
2392263508Sdim      return llvm::PointerUnion<VarTemplateDecl *,
2393263508Sdim                                VarTemplatePartialSpecializationDecl *>();
2394263508Sdim
2395263508Sdim    if (SpecializedPartialSpecialization *PartialSpec =
2396263508Sdim            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2397263508Sdim      return PartialSpec->PartialSpecialization;
2398263508Sdim
2399263508Sdim    return SpecializedTemplate.get<VarTemplateDecl *>();
2400263508Sdim  }
2401263508Sdim
2402263508Sdim  /// \brief Retrieve the variable template or variable template partial
2403263508Sdim  /// specialization which was specialized by this.
2404263508Sdim  llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2405263508Sdim  getSpecializedTemplateOrPartial() const {
2406263508Sdim    if (SpecializedPartialSpecialization *PartialSpec =
2407263508Sdim            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2408263508Sdim      return PartialSpec->PartialSpecialization;
2409263508Sdim
2410263508Sdim    return SpecializedTemplate.get<VarTemplateDecl *>();
2411263508Sdim  }
2412263508Sdim
2413263508Sdim  /// \brief Retrieve the set of template arguments that should be used
2414263508Sdim  /// to instantiate the initializer of the variable template or variable
2415263508Sdim  /// template partial specialization from which this variable template
2416263508Sdim  /// specialization was instantiated.
2417263508Sdim  ///
2418263508Sdim  /// \returns For a variable template specialization instantiated from the
2419263508Sdim  /// primary template, this function will return the same template arguments
2420263508Sdim  /// as getTemplateArgs(). For a variable template specialization instantiated
2421263508Sdim  /// from a variable template partial specialization, this function will the
2422263508Sdim  /// return deduced template arguments for the variable template partial
2423263508Sdim  /// specialization itself.
2424263508Sdim  const TemplateArgumentList &getTemplateInstantiationArgs() const {
2425263508Sdim    if (SpecializedPartialSpecialization *PartialSpec =
2426263508Sdim            SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2427263508Sdim      return *PartialSpec->TemplateArgs;
2428263508Sdim
2429263508Sdim    return getTemplateArgs();
2430263508Sdim  }
2431263508Sdim
2432263508Sdim  /// \brief Note that this variable template specialization is actually an
2433263508Sdim  /// instantiation of the given variable template partial specialization whose
2434263508Sdim  /// template arguments have been deduced.
2435263508Sdim  void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
2436263508Sdim                          const TemplateArgumentList *TemplateArgs) {
2437263508Sdim    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2438263508Sdim           "Already set to a variable template partial specialization!");
2439263508Sdim    SpecializedPartialSpecialization *PS =
2440263508Sdim        new (getASTContext()) SpecializedPartialSpecialization();
2441263508Sdim    PS->PartialSpecialization = PartialSpec;
2442263508Sdim    PS->TemplateArgs = TemplateArgs;
2443263508Sdim    SpecializedTemplate = PS;
2444263508Sdim  }
2445263508Sdim
2446263508Sdim  /// \brief Note that this variable template specialization is an instantiation
2447263508Sdim  /// of the given variable template.
2448263508Sdim  void setInstantiationOf(VarTemplateDecl *TemplDecl) {
2449263508Sdim    assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2450263508Sdim           "Previously set to a variable template partial specialization!");
2451263508Sdim    SpecializedTemplate = TemplDecl;
2452263508Sdim  }
2453263508Sdim
2454263508Sdim  /// \brief Sets the type of this specialization as it was written by
2455263508Sdim  /// the user.
2456263508Sdim  void setTypeAsWritten(TypeSourceInfo *T) {
2457263508Sdim    if (!ExplicitInfo)
2458263508Sdim      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2459263508Sdim    ExplicitInfo->TypeAsWritten = T;
2460263508Sdim  }
2461263508Sdim  /// \brief Gets the type of this specialization as it was written by
2462263508Sdim  /// the user, if it was so written.
2463263508Sdim  TypeSourceInfo *getTypeAsWritten() const {
2464263508Sdim    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
2465263508Sdim  }
2466263508Sdim
2467263508Sdim  /// \brief Gets the location of the extern keyword, if present.
2468263508Sdim  SourceLocation getExternLoc() const {
2469263508Sdim    return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2470263508Sdim  }
2471263508Sdim  /// \brief Sets the location of the extern keyword.
2472263508Sdim  void setExternLoc(SourceLocation Loc) {
2473263508Sdim    if (!ExplicitInfo)
2474263508Sdim      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2475263508Sdim    ExplicitInfo->ExternLoc = Loc;
2476263508Sdim  }
2477263508Sdim
2478263508Sdim  /// \brief Sets the location of the template keyword.
2479263508Sdim  void setTemplateKeywordLoc(SourceLocation Loc) {
2480263508Sdim    if (!ExplicitInfo)
2481263508Sdim      ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2482263508Sdim    ExplicitInfo->TemplateKeywordLoc = Loc;
2483263508Sdim  }
2484263508Sdim  /// \brief Gets the location of the template keyword, if present.
2485263508Sdim  SourceLocation getTemplateKeywordLoc() const {
2486263508Sdim    return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2487263508Sdim  }
2488263508Sdim
2489263508Sdim  void Profile(llvm::FoldingSetNodeID &ID) const {
2490263508Sdim    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
2491263508Sdim  }
2492263508Sdim
2493263508Sdim  static void Profile(llvm::FoldingSetNodeID &ID,
2494263508Sdim                      const TemplateArgument *TemplateArgs,
2495263508Sdim                      unsigned NumTemplateArgs, ASTContext &Context) {
2496263508Sdim    ID.AddInteger(NumTemplateArgs);
2497263508Sdim    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
2498263508Sdim      TemplateArgs[Arg].Profile(ID, Context);
2499263508Sdim  }
2500263508Sdim
2501263508Sdim  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2502263508Sdim  static bool classofKind(Kind K) {
2503263508Sdim    return K >= firstVarTemplateSpecialization &&
2504263508Sdim           K <= lastVarTemplateSpecialization;
2505263508Sdim  }
2506263508Sdim
2507263508Sdim  friend class ASTDeclReader;
2508263508Sdim  friend class ASTDeclWriter;
2509263508Sdim};
2510263508Sdim
2511263508Sdimclass VarTemplatePartialSpecializationDecl
2512263508Sdim    : public VarTemplateSpecializationDecl {
2513263508Sdim  virtual void anchor();
2514263508Sdim
2515263508Sdim  /// \brief The list of template parameters
2516263508Sdim  TemplateParameterList *TemplateParams;
2517263508Sdim
2518263508Sdim  /// \brief The source info for the template arguments as written.
2519263508Sdim  /// FIXME: redundant with TypeAsWritten?
2520263508Sdim  const ASTTemplateArgumentListInfo *ArgsAsWritten;
2521263508Sdim
2522263508Sdim  /// \brief The variable template partial specialization from which this
2523263508Sdim  /// variable template partial specialization was instantiated.
2524263508Sdim  ///
2525263508Sdim  /// The boolean value will be true to indicate that this variable template
2526263508Sdim  /// partial specialization was specialized at this level.
2527263508Sdim  llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2528263508Sdim  InstantiatedFromMember;
2529263508Sdim
2530263508Sdim  VarTemplatePartialSpecializationDecl(
2531263508Sdim      ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2532263508Sdim      SourceLocation IdLoc, TemplateParameterList *Params,
2533263508Sdim      VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2534263508Sdim      StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
2535263508Sdim      const ASTTemplateArgumentListInfo *ArgInfos);
2536263508Sdim
2537263508Sdim  VarTemplatePartialSpecializationDecl()
2538263508Sdim      : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization),
2539263508Sdim        TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {}
2540263508Sdim
2541263508Sdimpublic:
2542263508Sdim  static VarTemplatePartialSpecializationDecl *
2543263508Sdim  Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2544263508Sdim         SourceLocation IdLoc, TemplateParameterList *Params,
2545263508Sdim         VarTemplateDecl *SpecializedTemplate, QualType T,
2546263508Sdim         TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
2547263508Sdim         unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
2548263508Sdim
2549263508Sdim  static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
2550263508Sdim                                                                  unsigned ID);
2551263508Sdim
2552263508Sdim  VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2553263508Sdim    return cast<VarTemplatePartialSpecializationDecl>(
2554263508Sdim             static_cast<VarTemplateSpecializationDecl *>(
2555263508Sdim               this)->getMostRecentDecl());
2556263508Sdim  }
2557263508Sdim
2558263508Sdim  /// Get the list of template parameters
2559263508Sdim  TemplateParameterList *getTemplateParameters() const {
2560263508Sdim    return TemplateParams;
2561263508Sdim  }
2562263508Sdim
2563263508Sdim  /// Get the template arguments as written.
2564263508Sdim  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2565263508Sdim    return ArgsAsWritten;
2566263508Sdim  }
2567263508Sdim
2568263508Sdim  /// \brief Retrieve the member variable template partial specialization from
2569263508Sdim  /// which this particular variable template partial specialization was
2570263508Sdim  /// instantiated.
2571263508Sdim  ///
2572263508Sdim  /// \code
2573263508Sdim  /// template<typename T>
2574263508Sdim  /// struct Outer {
2575263508Sdim  ///   template<typename U> U Inner;
2576263508Sdim  ///   template<typename U> U* Inner<U*> = (U*)(0); // #1
2577263508Sdim  /// };
2578263508Sdim  ///
2579263508Sdim  /// template int* Outer<float>::Inner<int*>;
2580263508Sdim  /// \endcode
2581263508Sdim  ///
2582263508Sdim  /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2583263508Sdim  /// end up instantiating the partial specialization
2584263508Sdim  /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2585263508Sdim  /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2586263508Sdim  /// \c Outer<float>::Inner<U*>, this function would return
2587263508Sdim  /// \c Outer<T>::Inner<U*>.
2588263508Sdim  VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
2589263508Sdim    VarTemplatePartialSpecializationDecl *First =
2590263508Sdim        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2591263508Sdim    return First->InstantiatedFromMember.getPointer();
2592263508Sdim  }
2593263508Sdim
2594263508Sdim  void
2595263508Sdim  setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2596263508Sdim    VarTemplatePartialSpecializationDecl *First =
2597263508Sdim        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2598263508Sdim    First->InstantiatedFromMember.setPointer(PartialSpec);
2599263508Sdim  }
2600263508Sdim
2601263508Sdim  /// \brief Determines whether this variable template partial specialization
2602263508Sdim  /// was a specialization of a member partial specialization.
2603263508Sdim  ///
2604263508Sdim  /// In the following example, the member template partial specialization
2605263508Sdim  /// \c X<int>::Inner<T*> is a member specialization.
2606263508Sdim  ///
2607263508Sdim  /// \code
2608263508Sdim  /// template<typename T>
2609263508Sdim  /// struct X {
2610263508Sdim  ///   template<typename U> U Inner;
2611263508Sdim  ///   template<typename U> U* Inner<U*> = (U*)(0);
2612263508Sdim  /// };
2613263508Sdim  ///
2614263508Sdim  /// template<> template<typename T>
2615263508Sdim  /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2616263508Sdim  /// \endcode
2617263508Sdim  bool isMemberSpecialization() {
2618263508Sdim    VarTemplatePartialSpecializationDecl *First =
2619263508Sdim        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2620263508Sdim    return First->InstantiatedFromMember.getInt();
2621263508Sdim  }
2622263508Sdim
2623263508Sdim  /// \brief Note that this member template is a specialization.
2624263508Sdim  void setMemberSpecialization() {
2625263508Sdim    VarTemplatePartialSpecializationDecl *First =
2626263508Sdim        cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2627263508Sdim    assert(First->InstantiatedFromMember.getPointer() &&
2628263508Sdim           "Only member templates can be member template specializations");
2629263508Sdim    return First->InstantiatedFromMember.setInt(true);
2630263508Sdim  }
2631263508Sdim
2632263508Sdim  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2633263508Sdim  static bool classofKind(Kind K) {
2634263508Sdim    return K == VarTemplatePartialSpecialization;
2635263508Sdim  }
2636263508Sdim
2637263508Sdim  friend class ASTDeclReader;
2638263508Sdim  friend class ASTDeclWriter;
2639263508Sdim};
2640263508Sdim
2641263508Sdim/// Declaration of a variable template.
2642263508Sdimclass VarTemplateDecl : public RedeclarableTemplateDecl {
2643263508Sdim  static void DeallocateCommon(void *Ptr);
2644263508Sdim
2645263508Sdimprotected:
2646263508Sdim  /// \brief Data that is common to all of the declarations of a given
2647263508Sdim  /// variable template.
2648263508Sdim  struct Common : CommonBase {
2649263508Sdim    Common() : LazySpecializations() {}
2650263508Sdim
2651263508Sdim    /// \brief The variable template specializations for this variable
2652263508Sdim    /// template, including explicit specializations and instantiations.
2653263508Sdim    llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
2654263508Sdim
2655263508Sdim    /// \brief The variable template partial specializations for this variable
2656263508Sdim    /// template.
2657263508Sdim    llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
2658263508Sdim    PartialSpecializations;
2659263508Sdim
2660263508Sdim    /// \brief If non-null, points to an array of specializations (including
2661263508Sdim    /// partial specializations) known ownly by their external declaration IDs.
2662263508Sdim    ///
2663263508Sdim    /// The first value in the array is the number of of specializations/
2664263508Sdim    /// partial specializations that follow.
2665263508Sdim    uint32_t *LazySpecializations;
2666263508Sdim  };
2667263508Sdim
2668263508Sdim  /// \brief Load any lazily-loaded specializations from the external source.
2669263508Sdim  void LoadLazySpecializations() const;
2670263508Sdim
2671263508Sdim  /// \brief Retrieve the set of specializations of this variable template.
2672263508Sdim  llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
2673263508Sdim  getSpecializations() const;
2674263508Sdim
2675263508Sdim  /// \brief Retrieve the set of partial specializations of this class
2676263508Sdim  /// template.
2677263508Sdim  llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
2678263508Sdim  getPartialSpecializations();
2679263508Sdim
2680263508Sdim  VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
2681263508Sdim                  TemplateParameterList *Params, NamedDecl *Decl)
2682263508Sdim      : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {}
2683263508Sdim
2684263508Sdim  VarTemplateDecl(EmptyShell Empty)
2685263508Sdim      : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(),
2686263508Sdim                                 DeclarationName(), 0, 0) {}
2687263508Sdim
2688263508Sdim  CommonBase *newCommon(ASTContext &C) const;
2689263508Sdim
2690263508Sdim  Common *getCommonPtr() const {
2691263508Sdim    return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2692263508Sdim  }
2693263508Sdim
2694263508Sdimpublic:
2695263508Sdim  /// \brief Get the underlying variable declarations of the template.
2696263508Sdim  VarDecl *getTemplatedDecl() const {
2697263508Sdim    return static_cast<VarDecl *>(TemplatedDecl);
2698263508Sdim  }
2699263508Sdim
2700263508Sdim  /// \brief Returns whether this template declaration defines the primary
2701263508Sdim  /// variable pattern.
2702263508Sdim  bool isThisDeclarationADefinition() const {
2703263508Sdim    return getTemplatedDecl()->isThisDeclarationADefinition();
2704263508Sdim  }
2705263508Sdim
2706263508Sdim  VarTemplateDecl *getDefinition();
2707263508Sdim
2708263508Sdim  /// \brief Create a variable template node.
2709263508Sdim  static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
2710263508Sdim                                 SourceLocation L, DeclarationName Name,
2711263508Sdim                                 TemplateParameterList *Params, NamedDecl *Decl,
2712263508Sdim                                 VarTemplateDecl *PrevDecl);
2713263508Sdim
2714263508Sdim  /// \brief Create an empty variable template node.
2715263508Sdim  static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
2716263508Sdim
2717263508Sdim  /// \brief Return the specialization with the provided arguments if it exists,
2718263508Sdim  /// otherwise return the insertion point.
2719263508Sdim  VarTemplateSpecializationDecl *
2720263508Sdim  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
2721263508Sdim                     void *&InsertPos);
2722263508Sdim
2723263508Sdim  /// \brief Insert the specified specialization knowing that it is not already
2724263508Sdim  /// in. InsertPos must be obtained from findSpecialization.
2725263508Sdim  void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
2726263508Sdim
2727263508Sdim  VarTemplateDecl *getCanonicalDecl() {
2728263508Sdim    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
2729263508Sdim  }
2730263508Sdim  const VarTemplateDecl *getCanonicalDecl() const {
2731263508Sdim    return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
2732263508Sdim  }
2733263508Sdim
2734263508Sdim  /// \brief Retrieve the previous declaration of this variable template, or
2735263508Sdim  /// NULL if no such declaration exists.
2736263508Sdim  VarTemplateDecl *getPreviousDecl() {
2737263508Sdim    return cast_or_null<VarTemplateDecl>(
2738263508Sdim        static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2739263508Sdim  }
2740263508Sdim
2741263508Sdim  /// \brief Retrieve the previous declaration of this variable template, or
2742263508Sdim  /// NULL if no such declaration exists.
2743263508Sdim  const VarTemplateDecl *getPreviousDecl() const {
2744263508Sdim    return cast_or_null<VarTemplateDecl>(
2745263508Sdim            static_cast<const RedeclarableTemplateDecl *>(
2746263508Sdim              this)->getPreviousDecl());
2747263508Sdim  }
2748263508Sdim
2749263508Sdim  VarTemplateDecl *getInstantiatedFromMemberTemplate() {
2750263508Sdim    return cast_or_null<VarTemplateDecl>(
2751263508Sdim        RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
2752263508Sdim  }
2753263508Sdim
2754263508Sdim  /// \brief Return the partial specialization with the provided arguments if it
2755263508Sdim  /// exists, otherwise return the insertion point.
2756263508Sdim  VarTemplatePartialSpecializationDecl *
2757263508Sdim  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
2758263508Sdim                            void *&InsertPos);
2759263508Sdim
2760263508Sdim  /// \brief Insert the specified partial specialization knowing that it is not
2761263508Sdim  /// already in. InsertPos must be obtained from findPartialSpecialization.
2762263508Sdim  void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
2763263508Sdim                                void *InsertPos);
2764263508Sdim
2765263508Sdim  /// \brief Retrieve the partial specializations as an ordered list.
2766263508Sdim  void getPartialSpecializations(
2767263508Sdim      SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
2768263508Sdim
2769263508Sdim  /// \brief Find a variable template partial specialization which was
2770263508Sdim  /// instantiated
2771263508Sdim  /// from the given member partial specialization.
2772263508Sdim  ///
2773263508Sdim  /// \param D a member variable template partial specialization.
2774263508Sdim  ///
2775263508Sdim  /// \returns the variable template partial specialization which was
2776263508Sdim  /// instantiated
2777263508Sdim  /// from the given member partial specialization, or NULL if no such partial
2778263508Sdim  /// specialization exists.
2779263508Sdim  VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
2780263508Sdim      VarTemplatePartialSpecializationDecl *D);
2781263508Sdim
2782263508Sdim  typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
2783263508Sdim
2784263508Sdim  spec_iterator spec_begin() const {
2785263508Sdim    return makeSpecIterator(getSpecializations(), false);
2786263508Sdim  }
2787263508Sdim
2788263508Sdim  spec_iterator spec_end() const {
2789263508Sdim    return makeSpecIterator(getSpecializations(), true);
2790263508Sdim  }
2791263508Sdim
2792263508Sdim  typedef SpecIterator<VarTemplatePartialSpecializationDecl>
2793263508Sdim  partial_spec_iterator;
2794263508Sdim
2795263508Sdim  partial_spec_iterator partial_spec_begin() {
2796263508Sdim    return makeSpecIterator(getPartialSpecializations(), false);
2797263508Sdim  }
2798263508Sdim
2799263508Sdim  partial_spec_iterator partial_spec_end() {
2800263508Sdim    return makeSpecIterator(getPartialSpecializations(), true);
2801263508Sdim  }
2802263508Sdim
2803263508Sdim  // Implement isa/cast/dyncast support
2804263508Sdim  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2805263508Sdim  static bool classofKind(Kind K) { return K == VarTemplate; }
2806263508Sdim
2807263508Sdim  friend class ASTDeclReader;
2808263508Sdim  friend class ASTDeclWriter;
2809263508Sdim};
2810263508Sdim
2811193326Sed} /* end of namespace clang */
2812193326Sed
2813193326Sed#endif
2814