DeclTemplate.h revision f79079565e15e6a328372076ac5583af16c8dbce
1aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
2aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
3aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//                     The LLVM Compiler Infrastructure
4aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
5aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// This file is distributed under the University of Illinois Open Source
6aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// License. See LICENSE.TXT for details.
7aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
8aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
9aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
10aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//  This file defines the C++ template declaration subclasses.
11aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
12aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
13aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
14aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
15aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#define LLVM_CLANG_AST_DECLTEMPLATE_H
16aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor#include "clang/AST/DeclCXX.h"
185b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor#include "llvm/ADT/APSInt.h"
193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor#include "llvm/ADT/FoldingSet.h"
20f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor#include "llvm/ADT/PointerUnion.h"
213f3ce82674b44a58a2af7d90feb55acd906dd762Anders Carlsson#include <limits>
2255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
23aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregornamespace clang {
24aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
25aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList;
26aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateDecl;
27aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl;
28aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass ClassTemplateDecl;
29c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorclass ClassTemplatePartialSpecializationDecl;
30aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTypeParmDecl;
31aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl;
32aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl;
33aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
34f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor/// \brief Stores a template parameter of any kind.
35f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregortypedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
36f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor                            TemplateTemplateParmDecl*> TemplateParameter;
37f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
38aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateParameterList - Stores a list of template parameters for a
39aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateDecl and its derived classes.
40aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList {
41ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The location of the 'template' keyword.
42ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation TemplateLoc;
43ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
44ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The locations of the '<' and '>' angle brackets.
45ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation LAngleLoc, RAngleLoc;
46ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
47ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The number of template parameters in this template
48aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// parameter list.
49aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned NumParams;
50aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
51ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
52ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        Decl **Params, unsigned NumParams,
53ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
54aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
55aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
56ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  static TemplateParameterList *Create(ASTContext &C,
57ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
58ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
59ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       Decl **Params,
60ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
61ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
62aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
63aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// iterator - Iterates through the template parameters in this list.
64aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  typedef Decl** iterator;
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
66aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// const_iterator - Iterates through the template parameters in this list.
67aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  typedef Decl* const* const_iterator;
68aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
69aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator begin() { return reinterpret_cast<Decl **>(this + 1); }
70aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
71aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return reinterpret_cast<Decl * const *>(this + 1);
72aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
73aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator end() { return begin() + NumParams; }
74aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator end() const { return begin() + NumParams; }
75aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
76aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned size() const { return NumParams; }
77ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
78f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  Decl* getParam(unsigned Idx) {
79f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
80f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    return begin()[Idx];
81f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  }
82f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
8340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  const Decl* getParam(unsigned Idx) const {
8440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
8540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return begin()[Idx];
8640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
8740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
8862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// \btief Returns the minimum number of arguments needed to form a
8962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template specialization. This may be fewer than the number of
9062cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template parameters, if some of the parameters have default
910ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson  /// arguments or if there is a parameter pack.
9262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  unsigned getMinRequiredArguments() const;
9362cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
94ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getTemplateLoc() const { return TemplateLoc; }
95ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getLAngleLoc() const { return LAngleLoc; }
96ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getRAngleLoc() const { return RAngleLoc; }
9762cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
9862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  SourceRange getSourceRange() const {
9962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor    return SourceRange(TemplateLoc, RAngleLoc);
10062cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  }
101aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
102aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
103127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief Represents a template argument within a class template
104127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// specialization.
105127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgument {
106127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  union {
107127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    uintptr_t TypeOrValue;
108127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    struct {
109127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      char Value[sizeof(llvm::APSInt)];
110127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      void *Type;
111127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    } Integer;
112127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    struct {
113127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateArgument *Args;
114127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      unsigned NumArgs;
115127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      bool CopyArgs;
116127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    } Args;
117127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  };
118127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
119127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Location of the beginning of this template argument.
120127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation StartLoc;
121127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
122aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
123127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The type of template argument we're storing.
124127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  enum ArgKind {
125127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Null = 0,
126127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is a type. Its value is stored in the
127127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// TypeOrValue field.
128127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Type = 1,
129127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is a declaration
130127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Declaration = 2,
131127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is an integral value stored in an llvm::APSInt.
132127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Integral = 3,
133127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is a value- or type-dependent expression
134127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// stored in an Expr*.
135127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Expression = 4,
136127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
137127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is actually a parameter pack. Arguments are stored
138127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// in the Args struct.
139127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Pack = 5
140127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  } Kind;
141127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
142127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct an empty, invalid template argument.
143127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
144127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
145127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct a template type argument.
146127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
147127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
148127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Loc;
149aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
150127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
151127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct a template argument that refers to a
152127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration, which is either an external declaration or a
153127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template declaration.
154127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
155127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // FIXME: Need to be sure we have the "canonical" declaration!
156127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    TypeOrValue = reinterpret_cast<uintptr_t>(D);
157127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Loc;
158aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
15916e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor
160127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct an integral constant template argument.
161127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
162127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                   QualType Type)
163127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : Kind(Integral) {
164127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    new (Integer.Value) llvm::APSInt(Value);
165127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Integer.Type = Type.getAsOpaquePtr();
166127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Loc;
167127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
168127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
169127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct a template argument that is an expression.
170127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
171127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// This form of template argument only occurs in template argument
172127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// lists used for dependent types and for expression; it will not
173127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// occur in a non-dependent, canonical template argument list.
174127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(Expr *E);
175127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
176127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Copy constructor for a template argument.
177127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
178127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind == Integral) {
179127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
180127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Integer.Type = Other.Integer.Type;
181127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    } else if (Kind == Pack) {
182127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Args.NumArgs = Other.Args.NumArgs;
183127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Args.Args = new TemplateArgument[Args.NumArgs];
184127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      for (unsigned I = 0; I != Args.NumArgs; ++I)
185127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        Args.Args[I] = Other.Args.Args[I];
186127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    }
187127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    else
188127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TypeOrValue = Other.TypeOrValue;
189127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Other.StartLoc;
190127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
191127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
192127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument& operator=(const TemplateArgument& Other) {
193127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // FIXME: Does not provide the strong guarantee for exception
194127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // safety.
195127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    using llvm::APSInt;
19616e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor
197127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // FIXME: Handle Packs
198127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind != Pack && "FIXME: Handle packs");
199127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Other.Kind != Pack && "FIXME: Handle packs");
20016e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor
201127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind == Other.Kind && Kind == Integral) {
202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      // Copy integral values.
203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      *this->getAsIntegral() = *Other.getAsIntegral();
204127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Integer.Type = Other.Integer.Type;
205127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    } else {
206127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      // Destroy the current integral value, if that's what we're holding.
207127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      if (Kind == Integral)
208127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getAsIntegral()->~APSInt();
209127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
210127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Kind = Other.Kind;
211127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
212127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      if (Other.Kind == Integral) {
213127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
214127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        Integer.Type = Other.Integer.Type;
215127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      } else
216127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        TypeOrValue = Other.TypeOrValue;
217127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    }
218127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Other.StartLoc;
219127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
220127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return *this;
221127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
222127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
223127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateArgument() {
224127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    using llvm::APSInt;
225127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
226127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind == Integral)
227127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      getAsIntegral()->~APSInt();
228127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    else if (Kind == Pack && Args.CopyArgs)
229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      delete[] Args.Args;
230127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
231127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Return the kind of stored template argument.
233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ArgKind getKind() const { return Kind; }
234127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
235127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template argument has no value.
236127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool isNull() const { return Kind == Null; }
237127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
238127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as a type.
239127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getAsType() const {
240127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Type)
241127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return QualType();
242127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
243f79079565e15e6a328372076ac5583af16c8dbceMike Stump    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
244127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
245127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
246127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as a declaration.
247127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Decl *getAsDecl() const {
248127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Declaration)
249127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return 0;
250127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return reinterpret_cast<Decl *>(TypeOrValue);
251127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
252127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
253127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as an integral value.
254127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::APSInt *getAsIntegral() {
255127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Integral)
256127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return 0;
257127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
258127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
259127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
260127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const llvm::APSInt *getAsIntegral() const {
261127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return const_cast<TemplateArgument*>(this)->getAsIntegral();
262127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
263127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
264127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the type of the integral value.
265127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getIntegralType() const {
266127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Integral)
267127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return QualType();
268127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
269127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return QualType::getFromOpaquePtr(Integer.Type);
270127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
271127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
272127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setIntegralType(QualType T) {
273127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind == Integral &&
274127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor           "Cannot set the integral type of a non-integral template argument");
275127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Integer.Type = T.getAsOpaquePtr();
27616e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor  };
27716e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor
278127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as an expression.
279127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getAsExpr() const {
280127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Expression)
281127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return 0;
282127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
283127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return reinterpret_cast<Expr *>(TypeOrValue);
284aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
285199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
286127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Iterator that traverses the elements of a template argument pack.
287127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  typedef const TemplateArgument * pack_iterator;
288127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
289127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Iterator referencing the first argument of a template argument
290127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// pack.
291127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  pack_iterator pack_begin() const {
292127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind == Pack);
293127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return Args.Args;
294fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  }
295127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
296127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Iterator referencing one past the last argument of a template
297127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument pack.
298127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  pack_iterator pack_end() const {
299127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind == Pack);
300127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return Args.Args + Args.NumArgs;
301d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
302127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
303127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in the given template argument
304127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// pack.
305127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned pack_size() const {
306127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind == Pack);
307127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return Args.NumArgs;
308127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
309127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
310127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location where the template argument starts.
311127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getLocation() const { return StartLoc; }
312127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
313127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct a template argument pack.
314127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
315127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
316127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Used to insert TemplateArguments into FoldingSets.
317828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const {
318127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(Kind);
319127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    switch (Kind) {
320127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Null:
321127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
322127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
323127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Type:
324127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getAsType().Profile(ID);
325127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
326127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
327127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Declaration:
328828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor        ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
329127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
330127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
331127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Integral:
332127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getAsIntegral()->Profile(ID);
333127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getIntegralType().Profile(ID);
334127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
335127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
336127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Expression:
337828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor        getAsExpr()->Profile(ID, Context, true);
338127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
339127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
340127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Pack:
341127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        ID.AddInteger(Args.NumArgs);
342127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        for (unsigned I = 0; I != Args.NumArgs; ++I)
343828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          Args.Args[I].Profile(ID, Context);
344127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    }
345aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
346aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
347aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
348127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A helper class for making template argument lists.
349127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentListBuilder {
350127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument *StructuredArgs;
351127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned MaxStructuredArgs;
352127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArgs;
353127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
354127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument *FlatArgs;
355127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned MaxFlatArgs;
356127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArgs;
357127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
358127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool AddingToPack;
359127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned PackBeginIndex;
360127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
361aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
362127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
363127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                              unsigned NumTemplateArgs)
364127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
365127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NumStructuredArgs(0), FlatArgs(0),
366127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
367127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  AddingToPack(false), PackBeginIndex(0) { }
368127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
369127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Append(const TemplateArgument& Arg);
370127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void BeginPack();
371127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void EndPack();
372127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
373127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void ReleaseArgs();
374127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
375127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned flatSize() const {
376127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return NumFlatArgs;
377127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
378127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getFlatArguments() const {
379127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return FlatArgs;
380127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
381127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
382127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned structuredSize() const {
383127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat size.
384127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
385127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return flatSize();
386199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
387127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return NumStructuredArgs;
388d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
389127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getStructuredArguments() const {
390127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat args.
391127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
392127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return getFlatArguments();
393127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
394127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return StructuredArgs;
395aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
396aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
397aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
398127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A template argument list.
399127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor///
400127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// FIXME: In the future, this class will be extended to support
401127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// variadic templates and member templates, which will make some of
402127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the function names below make more sense.
403127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentList {
404127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template argument list.
405127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
406127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// The integer value will be non-zero to indicate that this
407127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list does not own the pointer.
408127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
409127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
410127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in this template
411127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument list.
412127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArguments;
413127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
414127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
415127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArguments;
416127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
417aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
418127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentList(ASTContext &Context,
419127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateArgumentListBuilder &Builder,
420127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool TakeArgs);
421127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
422127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateArgumentList();
423127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
424127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
425127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &get(unsigned Idx) const {
426127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Idx < NumFlatArguments && "Invalid template argument index");
427127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getFlatArgumentList()[Idx];
428127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
429127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
430127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
431127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
432127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
433127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in this
434127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list.
435127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned size() const { return NumFlatArguments; }
436127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
437127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in the
438127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// flattened template argument list.
439127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned flat_size() const { return NumFlatArguments; }
440127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
441127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the flattened template argument list.
442127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getFlatArgumentList() const {
443127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return FlatArguments.getPointer();
444127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
445127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
446127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
447127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
448127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Templates
449127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
450aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
451127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
452127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// class, function, etc.). The TemplateDecl class stores the list of template
453127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and a reference to the templated scoped declaration: the
454127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// underlying AST node.
455127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateDecl : public NamedDecl {
456127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
457127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // This is probably never used.
458127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
459127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name)
460127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0)
461127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
462d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
463127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with the given name and parameters.
464127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
465127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
466127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
467127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params)
468127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
469d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
470127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
471127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
472127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
473127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               NamedDecl *Decl)
474127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
475127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParams(Params) { }
476127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
477127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateDecl();
478d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
479127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the list of template parameters
480127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
481127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
482d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
483d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
484127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
485127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
486127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
487aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
488aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
489127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
490aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
491127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateDecl *D) { return true; }
492127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D) { return true; }
493127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const ClassTemplateDecl *D) { return true; }
494aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
495aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
496127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
497127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
498127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
499127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
500127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
501127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief Provides information about a function template specialization,
502127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
503127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
504127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
505127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
506127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The function template specialization that this structure
507127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
508127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
509127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
510127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The function template from which this function template
511127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
5121fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
5131fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// The bit will be 0 for an implicit instantiation, 1 for an explicit
5141fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// specialization.
5151fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 1> Template;
516127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
517127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
518127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
519127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
520127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
5211fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
5221fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
5231fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor
5241fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Determine whether this is an explicit specialization.
5251fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  bool isExplicitSpecialization() const { return Template.getInt(); }
5261fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor
5271fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Set whether this is an explicit specialization or an implicit
5281fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// instantiation.
5291fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  void setExplicitSpecialization(bool ES) {
5301fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor    Template.setInt(ES);
5311fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
5321fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor
533127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
534127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Profile(ID, TemplateArguments->getFlatArgumentList(),
535828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            TemplateArguments->flat_size(),
536828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            Function->getASTContext());
537127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
538127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
539127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static void
540127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
541828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
542127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
543127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
544828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
545127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
546127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
547127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
548127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// Declaration of a template function.
549127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateDecl : public TemplateDecl {
550127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
551127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Data that is common to all of the declarations of a given
552127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
553127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  struct Common {
554d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    Common() : InstantiatedFromMember(0) { }
555d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor
556127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// \brief The function template specializations for this function
557127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// template, including explicit specializations and instantiations.
558127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
559d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor
560d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// \brief The member function template from which this was most
561d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// directly instantiated (or null).
562d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    FunctionTemplateDecl *InstantiatedFromMember;
5633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
564127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
565127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief A pointer to the previous declaration (if this is a redeclaration)
566127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// or to the data that is common to all declarations of this function
567127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template.
568127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
569127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
570127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieves the "common" pointer shared by all
571127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// (re-)declarations of the same function template. Calling this routine
572127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// may implicitly allocate memory for the common pointer.
573127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Common *getCommonPtr();
574127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
575127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
576127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateParameterList *Params, NamedDecl *Decl)
577127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
578127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev((Common*)0) { }
579127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
5803e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
581127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Destroy(ASTContext &C);
582127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
583127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying function declaration of the template.
584127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *getTemplatedDecl() const {
585127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return static_cast<FunctionDecl*>(TemplatedDecl);
5863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
588127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the set of function template specializations of this
589127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
590127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
591127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getCommonPtr()->Specializations;
5923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
593127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
594127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
595127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
596127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const FunctionTemplateDecl *getPreviousDeclaration() const {
597127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
5983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
600127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
601127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
602127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl *getPreviousDeclaration() {
603127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
6043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
605127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
606127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the previous declaration of this function template.
607127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
608127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Prev)
609127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev = Prev;
610127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
611127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
612b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual FunctionTemplateDecl *getCanonicalDecl();
613b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis
614d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \brief Retrieve the member function template that this function template
615d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// was instantiated from.
616d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
617d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// This routine will return non-NULL for member function templates of
618d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// class templates.  For example, given:
619d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
620d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \code
621d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template <typename T>
622d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// struct X {
623d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///   template <typename U> void f();
624d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// };
625d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \endcode
626d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
627d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>::A<float> is a CXXMethodDecl (whose parent is X<int>, a
628d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
629d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
630d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
631d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
632d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// ClassTemplateDecl).
633d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
634d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \returns NULL if this is not an instantiation of a member function
635d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template.
636d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
637d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    return getCommonPtr()->InstantiatedFromMember;
638d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
639d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor
640d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
641d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    assert(!getCommonPtr()->InstantiatedFromMember);
642d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    getCommonPtr()->InstantiatedFromMember = FTD;
643d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
644d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor
645127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Create a template function node.
646127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
647127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
648127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
649127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
650127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
6513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
652127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
653127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D)
654127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { return D->getKind() == FunctionTemplate; }
655127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D)
656127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { return true; }
657127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
658d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
659127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
660127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
661127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
66240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
663127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
664127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// within a template parameter list. Because template parameter can be listed
665127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
666127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
667127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
668127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
669127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
670127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateParmPosition
671127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor{
672127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
673127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
674127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
675127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
676127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
6773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
678127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
679127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
680127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
6813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
682127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
683127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
684127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
685127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
6863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
687127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
688127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
689127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
6903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
691127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
692127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
6930b9247f129401b4849682b2e2bcdea8fc977068aDouglas Gregor
694127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
695127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
696127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
6973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
698127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
699127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
700127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
701127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
702127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
703127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
704127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
705127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
706127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// 'class' keyword.
707127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
7083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
709127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
710127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
711127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
7123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
713127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this is a parameter pack.
714127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool ParameterPack : 1;
715127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
716127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The location of the default argument, if any.
717127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation DefaultArgumentLoc;
7183e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
719127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
720127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType DefaultArgument;
721127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
722127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
723127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool Typename, QualType Type, bool ParameterPack)
724127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
725127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
726127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    TypeForDecl = Type.getTypePtr();
7273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
7283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
729127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
730127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
731127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L, unsigned D, unsigned P,
732127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
733127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
734c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
735127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
736127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
737127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// keyword.
738127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
739c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
740127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
741127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
742127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
743199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
744127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
745127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getDefaultArgument() const { return DefaultArgument; }
74640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
747127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
748127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
74940808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
750127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
751127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
752127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
753f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
754127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
755127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
756127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
757127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
758127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          bool Inherited) {
759127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
760127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgumentLoc = DefArgLoc;
761127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
762f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
76340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
764127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
765127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool isParameterPack() const { return ParameterPack; }
766fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
767127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
768127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
769127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == TemplateTypeParm;
7703e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
771127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
7723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
7733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
774127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
775127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
776127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
777127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
778127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
779127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
780127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public VarDecl, protected TemplateParmPosition {
781127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
782127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *DefaultArgument;
783127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
784127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
785127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          unsigned P, IdentifierInfo *Id, QualType T,
786a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis                          DeclaratorInfo *DInfo)
787a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, DInfo, VarDecl::None),
788127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
789127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
790127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
7911c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
792127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
793127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
794a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis         unsigned P, IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo);
7959ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
796127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
797127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
798127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
799127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
800127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
801127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
802127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
803fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
804127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
805127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
806127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
807127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
808127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
809127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
810127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
811127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
812127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
8133b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
814127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
815127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
816127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
817127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == NonTypeTemplateParm;
8183b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
819127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
8201c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
8211c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
822127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
823127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
824127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
825127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
826127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
827127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
828127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
829127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTemplateParmDecl
830127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
8317e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
832127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
833127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *DefaultArgument;
8347e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
835127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
836127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           unsigned D, unsigned P,
837127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
838127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
839127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
840127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
8417e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
842127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
843127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
844127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
845127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          unsigned P, IdentifierInfo *Id,
846127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
8477e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
848127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
849127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
850127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
851127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
852127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
853127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
854127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
8557e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
856127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
857127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
8587e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
859127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
860127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
8617e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
862127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
863127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
864127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
865127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
8667e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
867127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
868127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
869127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == TemplateTemplateParm;
8707e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  }
871127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
8727e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
8737e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
874cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor// \brief Describes the kind of template specialization that a
875cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor// particular template specialization declaration represents.
876cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregorenum TemplateSpecializationKind {
877cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was formed from a template-id but
878cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// has not yet been declared, defined, or instantiated.
879cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_Undeclared = 0,
880cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was declared or defined by an
881c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// explicit specialization (C++ [temp.expl.spec]) or partial
882c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// specialization (C++ [temp.class.spec]).
883cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_ExplicitSpecialization,
884cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was implicitly instantiated from a
885cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// template. (C++ [temp.inst]).
886cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_ImplicitInstantiation,
887cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was instantiated from a template
888cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// due to an explicit instantiation request (C++ [temp.explicit]).
889cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_ExplicitInstantiation
890cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor};
891cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
8923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
8933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
8943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
8963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
8973e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
8983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
9003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
9013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
9023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<>
9033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
9043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
9053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateSpecializationDecl
9063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
90737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
90837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Structure that stores information about a class template
90937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
91037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
91137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
91237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
91337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
91437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
91537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
91637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
91737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
91837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    TemplateArgumentList *TemplateArgs;
91937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
92037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
9213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
92237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
92337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
9243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
9257e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
9267e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  TemplateArgumentList TemplateArgs;
927cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
928cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
929cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
930cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  unsigned SpecializationKind : 2;
931cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
932c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
933c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
9347e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                  DeclContext *DC, SourceLocation L,
9353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
9368e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  TemplateArgumentListBuilder &Builder,
9378e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
9383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
9393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
9403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
9413e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
9423e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
94391fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
944cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
9453e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
94637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  virtual void Destroy(ASTContext& C);
94737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
9483e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
94937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
9503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
95137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the template arguments of the class template
95237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
9537e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  const TemplateArgumentList &getTemplateArgs() const {
9547e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    return TemplateArgs;
9553e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
9563e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
957cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
958cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
959cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
960cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
961cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
962cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
963cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
964cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
965cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
966cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
96737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
96837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
96937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
97037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
97137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *,
97237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
97337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
97437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
97537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiation)
97637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return (ClassTemplateDecl*)0;
97737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
97837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (SpecializedPartialSpecialization *PartialSpec
97937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
98037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
98137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
98237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return const_cast<ClassTemplateDecl*>(
98337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                             SpecializedTemplate.get<ClassTemplateDecl*>());
98437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
98537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
98637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
98737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
98837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
98937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
99037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
99137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
99237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
99337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
99437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
99537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
99637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
99737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
99837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (SpecializedPartialSpecialization *PartialSpec
99937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
100037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
100137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
100237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
100337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
100437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
100537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
100637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
100737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
100837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
100937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                          TemplateArgumentList *TemplateArgs) {
101037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedPartialSpecialization *PS
101137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
101237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
101337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
101437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
101537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
101637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
1017fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
1018fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
1019fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  void setTypeAsWritten(QualType T) {
1020fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor    TypeForDecl = T.getTypePtr();
1021fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
1022fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
1023c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1024828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
1025828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            getASTContext());
1026c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1027c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
10283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static void
10293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
1030828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
10310ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
10323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
1033828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
10343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
10353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const Decl *D) {
1037c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return D->getKind() == ClassTemplateSpecialization ||
1038c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor           D->getKind() == ClassTemplatePartialSpecialization;
10393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
10403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10413e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateSpecializationDecl *) {
10423e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return true;
10433e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
1044c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1045c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1046c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1047c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1048c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1049c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1050c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorclass ClassTemplatePartialSpecializationDecl
1051c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  : public ClassTemplateSpecializationDecl
1052c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor{
1053c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// \brief The list of template parameters
1054c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1055c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1056c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context,
1057c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         DeclContext *DC, SourceLocation L,
1058c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1059c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
10608e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                         TemplateArgumentListBuilder &Builder,
10618e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                               ClassTemplatePartialSpecializationDecl *PrevDecl)
10628e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor    : ClassTemplateSpecializationDecl(Context,
10638e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      ClassTemplatePartialSpecialization,
10648e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      DC, L, SpecializedTemplate, Builder,
10658e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      PrevDecl),
1066c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      TemplateParams(Params) { }
1067c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1068c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1069c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
1070c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
1071c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1072c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
107391fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
1074c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplatePartialSpecializationDecl *PrevDecl);
1075c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1076c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1077c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1078c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1079c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1080c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1081c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1082c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1083c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const Decl *D) {
1084c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return D->getKind() == ClassTemplatePartialSpecialization;
1085c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1086c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1087c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1088c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1089c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
10903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
10913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
10933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateDecl : public TemplateDecl {
10943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
10955953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
10965953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
10975953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  struct Common {
1098e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    Common() : InstantiatedFromMember(0) {}
1099e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
11005953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
11015953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
11025953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
11037da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1104c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1105c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
1106c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
1107c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1108c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
11097da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
11107da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1111e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1112e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// \brief The templated member class from which this was most
1113e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// directly instantiated (or null).
1114e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    ClassTemplateDecl *InstantiatedFromMember;
11155953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
11165953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11177532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  /// \brief Previous declaration of this class template.
11185953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ClassTemplateDecl *PreviousDeclaration;
11195953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11205953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Pointer to the data that is common to all of the
11215953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// declarations of this class template.
11225953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ///
11235953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// The first declaration of a class template (e.g., the declaration
11245953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// with no "previous declaration") owns this pointer.
11255953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  Common *CommonPtr;
11265953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
11285953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    TemplateParameterList *Params, NamedDecl *Decl,
11295953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    ClassTemplateDecl *PrevDecl, Common *CommonPtr)
11305953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
11315953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor      PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { }
11323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11335953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ~ClassTemplateDecl();
11343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
11363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Get the underlying class declarations of the template.
11373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
11383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
11393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11417da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \brief Retrieve the previous declaration of this template.
11427da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ClassTemplateDecl *getPreviousDeclaration() const {
11437da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    return PreviousDeclaration;
11447da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  }
1145b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis
1146b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual ClassTemplateDecl *getCanonicalDecl();
11477da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
11485953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// Create a class template node.
11493e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
11503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
11513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
11523e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
11535953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
11545953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
11553e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11563e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the set of specializations of this class template.
11573e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
11585953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    return CommonPtr->Specializations;
11593e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11603e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1161c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// \brief Retrieve the set of partial specializations of this class
1162c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// template.
1163c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
1164c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  getPartialSpecializations() {
1165c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return CommonPtr->PartialSpecializations;
1166c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1167c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1168b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1169b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1170b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1171b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief A dependent type that names a specialization of this class
1172b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1173b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1174b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1175b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1176b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
1177b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor
11787da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \brief Retrieve the type of the injected-class-name for this
11797da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// class template.
11807da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
11817da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
11827da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
11837da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
11847da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
11857da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
11867da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
11877da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
11887da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
11897da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
11907da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
11917da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
11927da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  QualType getInjectedClassNameType(ASTContext &Context);
11937da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1194e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \brief Retrieve the member class template that this class template was
1195e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// derived from.
1196e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1197e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// This routine will return non-NULL for templated member classes of
1198e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// class templates.  For example, given:
1199e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1200e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \code
1201e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// template <typename T>
1202e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// struct X {
1203e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///   template <typename U> struct A {};
1204e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// };
1205e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \endcode
1206e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1207e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
1208e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
1209e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
1210e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
1211e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
1212e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1213e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \returns null if this is not an instantiation of a member class template.
1214e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
1215e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    return CommonPtr->InstantiatedFromMember;
1216e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1217e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1218e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
1219e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    assert(!CommonPtr->InstantiatedFromMember);
1220e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    CommonPtr->InstantiatedFromMember = CTD;
1221e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1222e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
12233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
12243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const Decl *D)
12253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return D->getKind() == ClassTemplate; }
12263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateDecl *D)
12273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return true; }
12285953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
12295953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  virtual void Destroy(ASTContext& C);
12303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
12313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1232e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
1233e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregorinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
1234e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
1235e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
1236aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
1237aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1238aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
1239