DeclTemplate.h revision dd4a3b0065b9a7e7b00073df415a798886c090f3
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,
52bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                        NamedDecl **Params, unsigned NumParams,
53ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
54aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
55aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static TemplateParameterList *Create(ASTContext &C,
57ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
58ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
59bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor                                       NamedDecl **Params,
60ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
61ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
62aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
63aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// iterator - Iterates through the template parameters in this list.
64bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl** iterator;
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
66aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// const_iterator - Iterates through the template parameters in this list.
67bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  typedef NamedDecl* const* const_iterator;
68aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
69bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
70aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
71bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor    return reinterpret_cast<NamedDecl * 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
78bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  NamedDecl* getParam(unsigned Idx) {
79f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
80f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    return begin()[Idx];
81f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  }
82f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
83bf4ea56cdc376cef5a12abf6bf18dc34805c2226Douglas Gregor  const NamedDecl* 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  };
1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
119127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Location of the beginning of this template argument.
120127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation StartLoc;
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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,
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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;
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
142127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct an empty, invalid template argument.
143127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
1441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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  }
1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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  }
1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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  }
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \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);
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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  }
1911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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;
1961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
197127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // FIXME: Handle Packs
198127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind != Pack && "FIXME: Handle packs");
199127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Other.Kind != Pack && "FIXME: Handle packs");
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
201127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind == Other.Kind && Kind == Integral) {
202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      // Copy integral values.
203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      *this->getAsIntegral() = *Other.getAsIntegral();
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      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();
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
210127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Kind = Other.Kind;
2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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;
2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
220127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return *this;
221127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
2221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
223127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateArgument() {
224127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    using llvm::APSInt;
2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
226127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind == Integral)
227127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      getAsIntegral()->~APSInt();
228127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    else if (Kind == Pack && Args.CopyArgs)
229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      delete[] Args.Args;
230127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Return the kind of stored template argument.
233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ArgKind getKind() const { return Kind; }
2341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
235127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template argument has no value.
236127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool isNull() const { return Kind == Null; }
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
238127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as a type.
239127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getAsType() const {
240127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Type)
241127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return QualType();
2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
243f79079565e15e6a328372076ac5583af16c8dbceMike Stump    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
244127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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  }
2521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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  }
2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
260127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const llvm::APSInt *getAsIntegral() const {
261127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return const_cast<TemplateArgument*>(this)->getAsIntegral();
262127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
264127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the type of the integral value.
265127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getIntegralType() const {
266127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Integral)
267127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return QualType();
2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
269127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return QualType::getFromOpaquePtr(Integer.Type);
270127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
2711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
272127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setIntegralType(QualType T) {
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(Kind == Integral &&
274127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor           "Cannot set the integral type of a non-integral template argument");
275127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Integer.Type = T.getAsOpaquePtr();
27616e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor  };
2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
278127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as an expression.
279127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getAsExpr() const {
280127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Expression)
281127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return 0;
2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
283127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return reinterpret_cast<Expr *>(TypeOrValue);
284aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
286127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Iterator that traverses the elements of a template argument pack.
287127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  typedef const TemplateArgument * pack_iterator;
2881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \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  }
2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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  }
3021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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  }
3091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
310127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location where the template argument starts.
311127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getLocation() const { return StartLoc; }
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
313127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct a template argument pack.
314127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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;
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
323127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Type:
324127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getAsType().Profile(ID);
325127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
327127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Declaration:
328828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor        ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
329127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
331127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Integral:
332127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getAsIntegral()->Profile(ID);
333127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getIntegralType().Profile(ID);
334127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
336127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Expression:
337828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor        getAsExpr()->Profile(ID, Context, true);
338127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
3391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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;
3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
354127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument *FlatArgs;
355127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned MaxFlatArgs;
356127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArgs;
3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
358127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool AddingToPack;
359127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned PackBeginIndex;
3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
361aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
362127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
363127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                              unsigned NumTemplateArgs)
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
3651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  NumStructuredArgs(0), FlatArgs(0),
366127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
367127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  AddingToPack(false), PackBeginIndex(0) { }
3681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
369127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Append(const TemplateArgument& Arg);
370127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void BeginPack();
371127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void EndPack();
3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
373127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void ReleaseArgs();
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned flatSize() const {
376127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return NumFlatArgs;
377127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
378127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getFlatArguments() const {
379127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return FlatArgs;
380127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
3811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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();
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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();
3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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;
4091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
410127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in this template
411127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument list.
412127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArguments;
4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
414127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
415127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArguments;
4161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
417aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
418127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentList(ASTContext &Context,
419127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateArgumentListBuilder &Builder,
420127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool TakeArgs);
4211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
422127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateArgumentList();
4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
424127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument &get(unsigned Idx) const {
426127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Idx < NumFlatArguments && "Invalid template argument index");
427127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getFlatArgumentList()[Idx];
428127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
430127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
431127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
433127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in this
434127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list.
435127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned size() const { return NumFlatArguments; }
4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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; }
4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
441127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the flattened template argument list.
4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgument *getFlatArgumentList() const {
443127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return FlatArguments.getPointer();
444127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
445127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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)
4601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
461d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
462127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with the given name and parameters.
463127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
464127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
465127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
467d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
468127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
469127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
470127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
471127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               NamedDecl *Decl)
472127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
473127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParams(Params) { }
474127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
475127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateDecl();
476d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
477127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the list of template parameters
478127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
479127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
480d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
481d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
482127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
483127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
484127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
485aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
486aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
487127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
488aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
489127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateDecl *D) { return true; }
490127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D) { return true; }
491127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const ClassTemplateDecl *D) { return true; }
492aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
493aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
494127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
495127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
496127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
497127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
4981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// \brief Provides information about a function template specialization,
500127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
501127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
502127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
503127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template specialization that this structure
505127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
506127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
5071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The function template from which this function template
509127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
5101fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
511d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// The two bits are contain the top 4 values of TemplateSpecializationKind.
512d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
514127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
515127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
516127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
5171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5181fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
5191fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
520d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
521d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Determine what kind of template specialization this is.
522d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  TemplateSpecializationKind getTemplateSpecializationKind() const {
523d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    return (TemplateSpecializationKind)(Template.getInt() + 1);
524d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  }
525d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor
526d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  /// \brief Set the template specialization kind.
527d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor  void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
5281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(TSK != TSK_Undeclared &&
529d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor         "Cannot encode TSK_Undeclared for a function template specialization");
530d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor    Template.setInt(TSK - 1);
5311fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
5321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
533127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
5341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Profile(ID, TemplateArguments->getFlatArgumentList(),
535828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            TemplateArguments->flat_size(),
5361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            Function->getASTContext());
537127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
5381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
5401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
541828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
542127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
543127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
544828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
5451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
546127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
5471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
548127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// Declaration of a template function.
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass FunctionTemplateDecl : public TemplateDecl {
550127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
551127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Data that is common to all of the declarations of a given
552127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
553127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  struct Common {
554d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    Common() : InstantiatedFromMember(0) { }
5551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
556127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// \brief The function template specializations for this function
557127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// template, including explicit specializations and instantiations.
558127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
5591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
560d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// \brief The member function template from which this was most
561d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    /// directly instantiated (or null).
5621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    FunctionTemplateDecl *InstantiatedFromMember;
5633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
5641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
565127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief A pointer to the previous declaration (if this is a redeclaration)
566127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// or to the data that is common to all declarations of this function
567127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template.
568127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
5691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieves the "common" pointer shared by all
571127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// (re-)declarations of the same function template. Calling this routine
572127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// may implicitly allocate memory for the common pointer.
573127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Common *getCommonPtr();
5741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
575127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
576127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateParameterList *Params, NamedDecl *Decl)
577127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
578127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev((Common*)0) { }
5791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5803e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
581127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Destroy(ASTContext &C);
5821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
583127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying function declaration of the template.
584127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *getTemplatedDecl() const {
585127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return static_cast<FunctionDecl*>(TemplatedDecl);
5863e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
588127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the set of function template specializations of this
589127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
590127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
591127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getCommonPtr()->Specializations;
5923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
594127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
595127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
596127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const FunctionTemplateDecl *getPreviousDeclaration() const {
597127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
5983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
600127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
601127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
602127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl *getPreviousDeclaration() {
603127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
6043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
606127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the previous declaration of this function template.
607127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
608127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Prev)
609127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev = Prev;
610127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
6111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
612b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual FunctionTemplateDecl *getCanonicalDecl();
6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the member function template that this function template
615d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// was instantiated from.
616d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
617d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// This routine will return non-NULL for member function templates of
618d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// class templates.  For example, given:
619d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
620d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \code
621d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template <typename T>
622d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// struct X {
623d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///   template <typename U> void f();
624d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// };
625d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// \endcode
626d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
627d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>::A<float> is a CXXMethodDecl (whose parent is X<int>, a
6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
629d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
630d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
6311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
632d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// ClassTemplateDecl).
633d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  ///
6341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \returns NULL if this is not an instantiation of a member function
635d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  /// template.
636d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
637d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    return getCommonPtr()->InstantiatedFromMember;
638d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
6391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
640d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *FTD) {
641d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    assert(!getCommonPtr()->InstantiatedFromMember);
642d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor    getCommonPtr()->InstantiatedFromMember = FTD;
643d60e105e6d1624da647ef7dd35a9cf6fad1b763eDouglas Gregor  }
6441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
645127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Create a template function node.
646127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
647127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
648127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
649127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
650127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
6513e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
652127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
653127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D)
654127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { return D->getKind() == FunctionTemplate; }
655127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D)
656127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { return true; }
657127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
658d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
659127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
660127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
661127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
66240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
663127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
664127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// within a template parameter list. Because template parameter can be listed
665127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
666127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
667127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
668127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
669127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
6701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass TemplateParmPosition {
671127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
672127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
673127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
674127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
675127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
6763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
677127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
678127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
679127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
6803e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
681127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
682127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
683127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
684127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
6853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
686127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
687127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
688127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
6893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
690127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
691127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
6921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
693127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
694127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
695127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
6963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
697127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
698127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
699127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
700127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
701127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
702127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
703127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
704127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
705127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// 'class' keyword.
706127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
7073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
708127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
709127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
710127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
7113e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
712127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this is a parameter pack.
713127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool ParameterPack : 1;
714127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
715127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The location of the default argument, if any.
716127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation DefaultArgumentLoc;
7173e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
718127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
719127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType DefaultArgument;
720127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
7211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
722127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool Typename, QualType Type, bool ParameterPack)
723127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
7241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
725127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    TypeForDecl = Type.getTypePtr();
7263e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
7273e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
728127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
729127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
730127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L, unsigned D, unsigned P,
731127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
732127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
733c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
734127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
735127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
736127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// keyword.
737127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
738c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
739127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
740127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
741127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
742199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
743127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
744127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getDefaultArgument() const { return DefaultArgument; }
74540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
746127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
747127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
74840808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
749127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
750127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
751127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
752f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
753127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
754127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
755127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
756127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
757127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          bool Inherited) {
758127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
759127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgumentLoc = DefArgLoc;
760127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
761f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
76240808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
763127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
764127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool isParameterPack() const { return ParameterPack; }
765fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
766127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
767127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
768127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == TemplateTypeParm;
7693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
770127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
7713e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
7723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
773127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
774127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
775127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
776127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
777127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
778127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
779127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public VarDecl, protected TemplateParmPosition {
780127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
781127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *DefaultArgument;
782127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
783127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
784127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          unsigned P, IdentifierInfo *Id, QualType T,
785a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis                          DeclaratorInfo *DInfo)
786a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, DInfo, VarDecl::None),
7871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      TemplateParmPosition(D, P), DefaultArgument(0)
788127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
789127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
7901c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
791127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
792127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
793a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis         unsigned P, IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo);
7949ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
795127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
796127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
797127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
7981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
799127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
800127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
801127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
802fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
803127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
804127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
805127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
806127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
807127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
808127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
809127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
810127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
811127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
8123b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
813127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
814127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
815127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
816127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == NonTypeTemplateParm;
8173b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
818127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
8191c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
8201c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
821127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
822127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
823127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
824127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
825127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
826127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
827127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
828127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTemplateParmDecl
829127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
8307e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
831127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
832127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *DefaultArgument;
8337e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
834127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
835127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           unsigned D, unsigned P,
836127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
837127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
838127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
839127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
8407e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
841127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
842127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
843127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
844127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          unsigned P, IdentifierInfo *Id,
845127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
8467e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
847127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
848127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
849127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
8501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
851127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
852127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
853127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
8547e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
855127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
856127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
8577e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
858127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
859127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
8607e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
861127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
862127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
863127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
864127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
8657e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
866127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
867127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
868127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == TemplateTemplateParm;
8697e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  }
870127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
8717e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
8727e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
8733e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
8743e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
8753e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
8773e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
8783e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
8793e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8803e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
8813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
8821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
8831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// template<>
8843e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
8853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
8861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplateSpecializationDecl
8873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
8881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Structure that stores information about a class template
89037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
89137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
89237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
89337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
89437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
89537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
8961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
89737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
89837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
89937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    TemplateArgumentList *TemplateArgs;
90037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
9011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
90337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
90437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
9053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
9067e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
9077e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  TemplateArgumentList TemplateArgs;
908cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
9099cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief The point where this template was instantiated (if any)
9109cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation PointOfInstantiation;
9119cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
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);
9221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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
932136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall  virtual void getNameForDiagnostic(std::string &S,
933136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall                                    const PrintingPolicy &Policy,
934136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall                                    bool Qualified) const;
935136a6988960ac3aeb96f298da7a1a182db7217cdJohn McCall
9363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
93737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
9383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
9391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief Retrieve the template arguments of the class template
94037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
9411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const TemplateArgumentList &getTemplateArgs() const {
9427e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    return TemplateArgs;
9433e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
9443e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
945cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
946cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
947cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
948cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
949cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
950cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
951cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
952cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
953cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
954cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
9559cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  /// \brief Get the point of instantiation (if any), or null if none.
9569cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  SourceLocation getPointOfInstantiation() const {
9579cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    return PointOfInstantiation;
9589cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
9599cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
9609cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  void setPointOfInstantiation(SourceLocation Loc) {
9619cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    assert(Loc.isValid() && "point of instantiation must be valid!");
9629cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall    PointOfInstantiation = Loc;
9639cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall  }
9649cc7807e1622c2f945b607bdd39dd283df5e7bb5John McCall
96537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
96637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
96737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
96837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
9691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::PointerUnion<ClassTemplateDecl *,
97037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
97137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
97237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
973d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
974d0e3daf2b980b505e535d35b432c938c6d0208efDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
97537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return (ClassTemplateDecl*)0;
9761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
97837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
97937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
9801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return const_cast<ClassTemplateDecl*>(
98237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                             SpecializedTemplate.get<ClassTemplateDecl*>());
98337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
9841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
98637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
98737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
98837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
98937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
99037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
99137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
99237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
99337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
99437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
99537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
99637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
9971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SpecializedPartialSpecialization *PartialSpec
99837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
99937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
10001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
100237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
10031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
100537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
100637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
100737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
100837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                          TemplateArgumentList *TemplateArgs) {
10091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SpecializedPartialSpecialization *PS
101037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
101137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
101237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
101337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
101437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
10151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1016fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
1017fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
1018fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  void setTypeAsWritten(QualType T) {
1019fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor    TypeForDecl = T.getTypePtr();
1020fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
1021fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
1022c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1023828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
1024828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            getASTContext());
1025c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1026c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
10271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static void
10281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
1029828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
10300ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
10313e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
1032828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
10333e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
10343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Decl *D) {
1036c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return D->getKind() == ClassTemplateSpecialization ||
1037c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor           D->getKind() == ClassTemplatePartialSpecialization;
10383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
10393e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10403e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateSpecializationDecl *) {
10413e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return true;
10423e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
1043c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1044c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1045c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1046c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1047c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1048c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
10491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass ClassTemplatePartialSpecializationDecl
10501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  : public ClassTemplateSpecializationDecl {
10511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  /// \brief The list of template parameters
1052c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1053c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1054c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context,
1055c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         DeclContext *DC, SourceLocation L,
1056c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1057c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
10588e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                         TemplateArgumentListBuilder &Builder,
10598e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                               ClassTemplatePartialSpecializationDecl *PrevDecl)
10601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    : ClassTemplateSpecializationDecl(Context,
10618e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      ClassTemplatePartialSpecialization,
10628e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      DC, L, SpecializedTemplate, Builder,
10638e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      PrevDecl),
1064c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      TemplateParams(Params) { }
1065c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1066c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1067c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
1068c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
1069c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1070c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
107191fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
1072c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplatePartialSpecializationDecl *PrevDecl);
1073c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1074c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1075c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1076c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1077c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1078c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1079c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1080c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
10811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const Decl *D) {
1082c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return D->getKind() == ClassTemplatePartialSpecialization;
1083c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1084c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1085c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1086c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1087c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
10883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
10893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
10913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateDecl : public TemplateDecl {
10923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
10935953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
10945953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
10955953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  struct Common {
1096e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    Common() : InstantiatedFromMember(0) {}
1097e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
10985953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
10995953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
11005953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
11017da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1102c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1103c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
11041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
1105c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1106c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
11077da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
11087da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1109e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1110e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// \brief The templated member class from which this was most
1111e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// directly instantiated (or null).
1112e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    ClassTemplateDecl *InstantiatedFromMember;
11135953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
11145953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11157532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  /// \brief Previous declaration of this class template.
11165953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ClassTemplateDecl *PreviousDeclaration;
11175953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11185953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Pointer to the data that is common to all of the
11195953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// declarations of this class template.
11201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ///
11215953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// The first declaration of a class template (e.g., the declaration
11225953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// with no "previous declaration") owns this pointer.
11235953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  Common *CommonPtr;
11241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
11265953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    TemplateParameterList *Params, NamedDecl *Decl,
11275953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    ClassTemplateDecl *PrevDecl, Common *CommonPtr)
11285953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
11295953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor      PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { }
11303e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11315953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ~ClassTemplateDecl();
11323e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11333e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
11343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Get the underlying class declarations of the template.
11353e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
11363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
11373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11383e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11397da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \brief Retrieve the previous declaration of this template.
11407da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ClassTemplateDecl *getPreviousDeclaration() const {
11417da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    return PreviousDeclaration;
11427da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  }
11431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1144b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual ClassTemplateDecl *getCanonicalDecl();
11457da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
11465953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// Create a class template node.
11473e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
11483e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
11493e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
11503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
11515953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
11525953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
11533e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the set of specializations of this class template.
11553e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
11565953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    return CommonPtr->Specializations;
11573e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11583e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1159c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// \brief Retrieve the set of partial specializations of this class
1160c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// template.
1161c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
1162c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  getPartialSpecializations() {
1163c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return CommonPtr->PartialSpecializations;
1164c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1165c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1166b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1167b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1168b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1169b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief A dependent type that names a specialization of this class
1170b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1171b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1172b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1173b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1174b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
11751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11767da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \brief Retrieve the type of the injected-class-name for this
11777da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// class template.
11787da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
11797da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
11807da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
11817da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
11827da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
11837da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
11847da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
11857da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
11867da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
11877da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
11887da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
11897da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
11907da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  QualType getInjectedClassNameType(ASTContext &Context);
11917da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1192e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \brief Retrieve the member class template that this class template was
1193e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// derived from.
1194e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1195e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// This routine will return non-NULL for templated member classes of
1196e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// class templates.  For example, given:
1197e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1198e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \code
1199e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// template <typename T>
1200e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// struct X {
1201e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///   template <typename U> struct A {};
1202e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// };
1203e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \endcode
1204e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1205e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
1206e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
1207e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
1208e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
1209e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
1210e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1211e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \returns null if this is not an instantiation of a member class template.
1212e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
1213e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    return CommonPtr->InstantiatedFromMember;
1214e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1215e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1216e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
1217e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    assert(!CommonPtr->InstantiatedFromMember);
1218e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    CommonPtr->InstantiatedFromMember = CTD;
1219e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1220e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
12213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
12223e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const Decl *D)
12233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return D->getKind() == ClassTemplate; }
12243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateDecl *D)
12253e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return true; }
12265953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
12275953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  virtual void Destroy(ASTContext& C);
12283e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
12293e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1230dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// Declaration of a friend template.  For example:
1231dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///
1232dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall/// template <typename T> class A {
1233dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   friend class MyVector<T>; // not a friend template
1234dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   template <typename U> friend class B; // friend template
1235dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall///   template <typename U> friend class Foo<T>::Nested; // friend template
1236dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallclass FriendTemplateDecl : public Decl {
1237dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
1238dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  typedef llvm::PointerUnion<NamedDecl*,Type*> FriendUnion;
1239dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1240dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallprivate:
1241dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The number of template parameters;  always non-zero.
1242dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned NumParams;
1243dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1244dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The parameter list.
1245dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList **Params;
1246dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1247dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // The declaration that's a friend of this class.
1248dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendUnion Friend;
1249dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1250dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Location of the 'friend' specifier.
1251dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation FriendLoc;
1252dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1253dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1254dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
1255dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     unsigned NParams,
1256dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     TemplateParameterList **Params,
1257dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     FriendUnion Friend,
1258dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                     SourceLocation FriendLoc)
1259dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    : Decl(Decl::FriendTemplate, DC, Loc),
1260dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      NumParams(NParams),
1261dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Params(Params),
1262dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      Friend(Friend),
1263dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      FriendLoc(FriendLoc)
1264dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  {}
1265dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1266dd4a3b0065b9a7e7b00073df415a798886c090f3John McCallpublic:
1267dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static FriendTemplateDecl *Create(ASTContext &Context,
1268dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    DeclContext *DC, SourceLocation Loc,
1269dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    unsigned NParams,
1270dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    TemplateParameterList **Params,
1271dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    FriendUnion Friend,
1272dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall                                    SourceLocation FriendLoc);
1273dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1274dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated type (or
1275dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a dependent member type of a templated type), return that
1276dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// type;  otherwise return null.
1277dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  Type *getFriendType() const {
1278dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Friend.dyn_cast<Type*>();
1279dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1280dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1281dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// If this friend declaration names a templated function (or
1282dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// a member function of a templated type), return that type;
1283dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// otherwise return null.
1284dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  NamedDecl *getFriendDecl() const {
1285dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Friend.dyn_cast<NamedDecl*>();
1286dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1287dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1288dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  /// Retrieves the location of the 'friend' keyword.
1289dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  SourceLocation getFriendLoc() const {
1290dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return FriendLoc;
1291dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1292dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1293dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  TemplateParameterList *getTemplateParameterList(unsigned i) const {
1294dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    assert(i <= NumParams);
1295dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return Params[i];
1296dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1297dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1298dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  unsigned getNumTemplateParameters() const {
1299dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return NumParams;
1300dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1301dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1302dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  // Implement isa/cast/dyncast/etc.
1303dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static bool classof(const Decl *D) {
1304dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall    return D->getKind() == Decl::FriendTemplate;
1305dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  }
1306dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  static bool classof(const FriendTemplateDecl *D) { return true; }
1307dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall};
1308dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
1309e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
13101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
1311e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
1312e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
1313aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
1314aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1315aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
1316