DeclTemplate.h revision d0e3daf2b980b505e535d35b432c938c6d0208ef
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  ///
513d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
514d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
515127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
516127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
517127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
518127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
519127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
5201fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
5211fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
522d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
523d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Determine what kind of template specialization this is.
524d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
525d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    return (TemplateSpecializationKind)(Template.getInt() + 1);
526d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  }
527d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
528d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Set the template specialization kind.
529d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
530d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    assert(TSK != TSK_Undeclared &&
531d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor         "Cannot encode TSK_Undeclared for a function template specialization");
532d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    Template.setInt(TSK - 1);
5331fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
5341fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor
535127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
536127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Profile(ID, TemplateArguments->getFlatArgumentList(),
537828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            TemplateArguments->flat_size(),
538828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            Function->getASTContext());
539127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
540127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
541127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static void
542127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
543828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
544127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
545127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
546828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
547127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
548127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
549127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
550127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// Declaration of a template function.
551127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateDecl : public TemplateDecl {
552127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
553127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Data that is common to all of the declarations of a given
554127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
555127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  struct Common {
556d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    Common() : InstantiatedFromMember(0) { }
557d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor
558127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// \brief The function template specializations for this function
559127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// template, including explicit specializations and instantiations.
560127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
561d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor
562d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// \brief The member function template from which this was most
563d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// directly instantiated (or null).
564d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    FunctionTemplateDecl *InstantiatedFromMember;
5653e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
566127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
567127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief A pointer to the previous declaration (if this is a redeclaration)
568127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// or to the data that is common to all declarations of this function
569127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template.
570127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
571127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
572127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieves the "common" pointer shared by all
573127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// (re-)declarations of the same function template. Calling this routine
574127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// may implicitly allocate memory for the common pointer.
575127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Common *getCommonPtr();
576127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
577127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
578127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateParameterList *Params, NamedDecl *Decl)
579127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
580127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev((Common*)0) { }
581127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
5823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
583127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Destroy(ASTContext &C);
584127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
585127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying function declaration of the template.
586127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *getTemplatedDecl() const {
587127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return static_cast<FunctionDecl*>(TemplatedDecl);
5883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
590127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the set of function template specializations of this
591127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
592127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
593127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getCommonPtr()->Specializations;
5943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
595127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
596127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
597127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
598127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const FunctionTemplateDecl *getPreviousDeclaration() const {
599127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
6003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
602127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
603127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
604127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl *getPreviousDeclaration() {
605127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
6063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
607127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
608127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the previous declaration of this function template.
609127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
610127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Prev)
611127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev = Prev;
612127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
613127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
614b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual FunctionTemplateDecl *getCanonicalDecl();
615b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis
616d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \brief Retrieve the member function template that this function template
617d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// was instantiated from.
618d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
619d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// This routine will return non-NULL for member function templates of
620d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// class templates.  For example, given:
621d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
622d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \code
623d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template <typename T>
624d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// struct X {
625d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///   template <typename U> void f();
626d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// };
627d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \endcode
628d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
629d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>::A<float> is a CXXMethodDecl (whose parent is X<int>, a
630d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
631d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
632d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
633d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
634d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// ClassTemplateDecl).
635d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
636d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \returns NULL if this is not an instantiation of a member function
637d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template.
638d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
639d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    return getCommonPtr()->InstantiatedFromMember;
640d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
641d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor
642d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
643d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    assert(!getCommonPtr()->InstantiatedFromMember);
644d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    getCommonPtr()->InstantiatedFromMember = FTD;
645d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
646d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor
647127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Create a template function node.
648127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
649127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
650127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
651127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
652127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
6533e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
654127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
655127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D)
656127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { return D->getKind() == FunctionTemplate; }
657127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D)
658127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { return true; }
659127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
660d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
661127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
662127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
663127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
66440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
665127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
666127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// within a template parameter list. Because template parameter can be listed
667127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
668127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
669127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
670127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
671127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
672127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateParmPosition
673127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor{
674127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
675127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
676127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
677127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
678127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
6793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
680127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
681127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
682127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
6833e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
684127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
685127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
686127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
687127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
6883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
689127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
690127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
691127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
6923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
693127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
694127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
6950b9247f129401b4849682b2e2bcdea8fc977068aDouglas Gregor
696127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
697127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
698127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
6993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
700127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
701127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
702127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
703127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
704127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
705127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
706127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
707127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
708127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// 'class' keyword.
709127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
7103e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
711127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
712127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
713127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
7143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
715127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this is a parameter pack.
716127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool ParameterPack : 1;
717127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
718127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The location of the default argument, if any.
719127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation DefaultArgumentLoc;
7203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
721127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
722127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType DefaultArgument;
723127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
724127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
725127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool Typename, QualType Type, bool ParameterPack)
726127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
727127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
728127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    TypeForDecl = Type.getTypePtr();
7293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
7303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
731127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
732127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
733127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L, unsigned D, unsigned P,
734127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
735127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
736c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
737127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
738127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
739127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// keyword.
740127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
741c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
742127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
743127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
744127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
745199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
746127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
747127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getDefaultArgument() const { return DefaultArgument; }
74840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
749127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
750127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
75140808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
752127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
753127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
754127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
755f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
756127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
757127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
758127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
759127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
760127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          bool Inherited) {
761127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
762127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgumentLoc = DefArgLoc;
763127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
764f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
76540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
766127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
767127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool isParameterPack() const { return ParameterPack; }
768fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
769127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
770127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
771127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == TemplateTypeParm;
7723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
773127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
7743e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
7753e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
776127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
777127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
778127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
779127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
780127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
781127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
782127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public VarDecl, protected TemplateParmPosition {
783127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
784127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *DefaultArgument;
785127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
786127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
787127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          unsigned P, IdentifierInfo *Id, QualType T,
788a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis                          DeclaratorInfo *DInfo)
789a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, DInfo, VarDecl::None),
790127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
791127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
792127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
7931c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
794127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
795127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
796a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis         unsigned P, IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo);
7979ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
798127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
799127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
800127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
801127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
802127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
803127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
804127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
805fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
806127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
807127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
808127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
809127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
810127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
811127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
812127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
813127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
814127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
8153b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
816127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
817127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
818127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
819127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == NonTypeTemplateParm;
8203b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
821127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
8221c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
8231c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
824127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
825127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
826127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
827127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
828127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
829127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
830127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
831127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTemplateParmDecl
832127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
8337e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
834127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
835127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *DefaultArgument;
8367e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
837127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
838127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           unsigned D, unsigned P,
839127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
840127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
841127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
842127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
8437e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
844127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
845127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
846127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
847127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          unsigned P, IdentifierInfo *Id,
848127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
8497e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
850127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
851127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
852127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
853127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
854127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
855127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
856127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
8577e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
858127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
859127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
8607e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
861127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
862127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
8637e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
864127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
865127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
866127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
867127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
8687e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
869127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
870127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
871127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == TemplateTemplateParm;
8727e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  }
873127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
8747e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
8757e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
8763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
8773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
8783e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
8803e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
8813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
8823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8833e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
8843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
8853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<>
8873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
8883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
8893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateSpecializationDecl
8903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
89137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
89237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Structure that stores information about a class template
89337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
89437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
89537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
89637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
89737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
89837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
89937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
90037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
90137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
90237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    TemplateArgumentList *TemplateArgs;
90337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
90437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
9053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
90637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
90737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
9083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
9097e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
9107e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  TemplateArgumentList TemplateArgs;
911cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
912cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
913cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
914d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  unsigned SpecializationKind : 3;
915cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
916c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
917c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
9187e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                  DeclContext *DC, SourceLocation L,
9193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
9208e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  TemplateArgumentListBuilder &Builder,
9218e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
9223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
9233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
9243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
9253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
9263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
92791fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
928cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
9293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
93037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  virtual void Destroy(ASTContext& C);
93137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
9323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
93337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
9343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
93537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the template arguments of the class template
93637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
9377e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  const TemplateArgumentList &getTemplateArgs() const {
9387e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    return TemplateArgs;
9393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
9403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
941cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
942cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
943cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
944cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
945cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
946cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
947cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
948cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
949cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
950cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
95137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
95237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
95337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
95437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
95537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *,
95637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
95737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
95837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
959d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
960d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
96137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return (ClassTemplateDecl*)0;
96237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
96337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (SpecializedPartialSpecialization *PartialSpec
96437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
96537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
96637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
96737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return const_cast<ClassTemplateDecl*>(
96837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                             SpecializedTemplate.get<ClassTemplateDecl*>());
96937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
97037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
97137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
97237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
97337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
97437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
97537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
97637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
97737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
97837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
97937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
98037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
98137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
98237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
98337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (SpecializedPartialSpecialization *PartialSpec
98437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
98537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
98637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
98737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
98837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
98937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
99037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
99137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
99237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
99337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
99437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                          TemplateArgumentList *TemplateArgs) {
99537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedPartialSpecialization *PS
99637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
99737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
99837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
99937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
100037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
100137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
1002fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
1003fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
1004fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  void setTypeAsWritten(QualType T) {
1005fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor    TypeForDecl = T.getTypePtr();
1006fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
1007fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
1008c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1009828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
1010828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            getASTContext());
1011c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1012c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
10133e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static void
10143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
1015828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
10160ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
10173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
1018828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
10193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
10203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const Decl *D) {
1022c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return D->getKind() == ClassTemplateSpecialization ||
1023c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor           D->getKind() == ClassTemplatePartialSpecialization;
10243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
10253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateSpecializationDecl *) {
10273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return true;
10283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
1029c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1030c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1031c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1032c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1033c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1034c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1035c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorclass ClassTemplatePartialSpecializationDecl
1036c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  : public ClassTemplateSpecializationDecl
1037c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor{
1038c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// \brief The list of template parameters
1039c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1040c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1041c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context,
1042c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         DeclContext *DC, SourceLocation L,
1043c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1044c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
10458e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                         TemplateArgumentListBuilder &Builder,
10468e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                               ClassTemplatePartialSpecializationDecl *PrevDecl)
10478e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor    : ClassTemplateSpecializationDecl(Context,
10488e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      ClassTemplatePartialSpecialization,
10498e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      DC, L, SpecializedTemplate, Builder,
10508e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      PrevDecl),
1051c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      TemplateParams(Params) { }
1052c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1053c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1054c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
1055c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
1056c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1057c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
105891fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
1059c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplatePartialSpecializationDecl *PrevDecl);
1060c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1061c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1062c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1063c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1064c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1065c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1066c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1067c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1068c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const Decl *D) {
1069c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return D->getKind() == ClassTemplatePartialSpecialization;
1070c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1071c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1072c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1073c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1074c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
10753e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
10763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
10783e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateDecl : public TemplateDecl {
10793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
10805953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
10815953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
10825953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  struct Common {
1083e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    Common() : InstantiatedFromMember(0) {}
1084e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
10855953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
10865953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
10875953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
10887da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1089c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1090c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
1091c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
1092c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1093c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
10947da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
10957da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1096e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1097e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// \brief The templated member class from which this was most
1098e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// directly instantiated (or null).
1099e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    ClassTemplateDecl *InstantiatedFromMember;
11005953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
11015953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11027532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  /// \brief Previous declaration of this class template.
11035953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ClassTemplateDecl *PreviousDeclaration;
11045953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11055953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Pointer to the data that is common to all of the
11065953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// declarations of this class template.
11075953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ///
11085953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// The first declaration of a class template (e.g., the declaration
11095953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// with no "previous declaration") owns this pointer.
11105953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  Common *CommonPtr;
11115953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
11135953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    TemplateParameterList *Params, NamedDecl *Decl,
11145953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    ClassTemplateDecl *PrevDecl, Common *CommonPtr)
11155953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
11165953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor      PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { }
11173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11185953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ~ClassTemplateDecl();
11193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
11213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Get the underlying class declarations of the template.
11223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
11233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
11243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11267da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \brief Retrieve the previous declaration of this template.
11277da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ClassTemplateDecl *getPreviousDeclaration() const {
11287da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    return PreviousDeclaration;
11297da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  }
1130b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis
1131b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual ClassTemplateDecl *getCanonicalDecl();
11327da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
11335953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// Create a class template node.
11343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
11353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
11363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
11373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
11385953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
11395953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
11403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11413e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the set of specializations of this class template.
11423e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
11435953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    return CommonPtr->Specializations;
11443e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11453e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1146c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// \brief Retrieve the set of partial specializations of this class
1147c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// template.
1148c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
1149c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  getPartialSpecializations() {
1150c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return CommonPtr->PartialSpecializations;
1151c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1152c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1153b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1154b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1155b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1156b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief A dependent type that names a specialization of this class
1157b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1158b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1159b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1160b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1161b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
1162b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor
11637da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \brief Retrieve the type of the injected-class-name for this
11647da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// class template.
11657da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
11667da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
11677da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
11687da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
11697da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
11707da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
11717da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
11727da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
11737da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
11747da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
11757da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
11767da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
11777da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  QualType getInjectedClassNameType(ASTContext &Context);
11787da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1179e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \brief Retrieve the member class template that this class template was
1180e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// derived from.
1181e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1182e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// This routine will return non-NULL for templated member classes of
1183e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// class templates.  For example, given:
1184e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1185e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \code
1186e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// template <typename T>
1187e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// struct X {
1188e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///   template <typename U> struct A {};
1189e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// };
1190e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \endcode
1191e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1192e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
1193e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
1194e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
1195e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
1196e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
1197e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1198e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \returns null if this is not an instantiation of a member class template.
1199e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
1200e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    return CommonPtr->InstantiatedFromMember;
1201e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1202e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1203e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
1204e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    assert(!CommonPtr->InstantiatedFromMember);
1205e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    CommonPtr->InstantiatedFromMember = CTD;
1206e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1207e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
12083e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
12093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const Decl *D)
12103e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return D->getKind() == ClassTemplate; }
12113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateDecl *D)
12123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return true; }
12135953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
12145953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  virtual void Destroy(ASTContext& C);
12153e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
12163e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1217e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
1218e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregorinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
1219e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
1220e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
1221aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
1222aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1223aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
1224