DeclTemplate.h revision a5d82000f7b173a0a5ce34dc8c09a03f98d9e439
1aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
2aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
3aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//                     The LLVM Compiler Infrastructure
4aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
5aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// This file is distributed under the University of Illinois Open Source
6aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor// License. See LICENSE.TXT for details.
7aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
8aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
9aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
10aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//  This file defines the C++ template declaration subclasses.
11aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//
12aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor//===----------------------------------------------------------------------===//
13aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
14aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
15aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#define LLVM_CLANG_AST_DECLTEMPLATE_H
16aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1755f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor#include "clang/AST/DeclCXX.h"
185b0f752655cc94b970113235110b56a722eb40d4Douglas Gregor#include "llvm/ADT/APSInt.h"
193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor#include "llvm/ADT/FoldingSet.h"
20f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor#include "llvm/ADT/PointerUnion.h"
213f3ce82674b44a58a2af7d90feb55acd906dd762Anders Carlsson#include <limits>
2255f6b14230c94272efbbcdd89a92224c8db9f225Douglas Gregor
23aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregornamespace clang {
24aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
25aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList;
26aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateDecl;
27aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass FunctionTemplateDecl;
28aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass ClassTemplateDecl;
29c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorclass ClassTemplatePartialSpecializationDecl;
30aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTypeParmDecl;
31aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass NonTypeTemplateParmDecl;
32aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateTemplateParmDecl;
33aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
34f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor/// \brief Stores a template parameter of any kind.
35f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregortypedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
36f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor                            TemplateTemplateParmDecl*> TemplateParameter;
37f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
38aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateParameterList - Stores a list of template parameters for a
39aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor/// TemplateDecl and its derived classes.
40aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorclass TemplateParameterList {
41ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The location of the 'template' keyword.
42ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation TemplateLoc;
43ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
44ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The locations of the '<' and '>' angle brackets.
45ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation LAngleLoc, RAngleLoc;
46ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
47ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  /// The number of template parameters in this template
48aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// parameter list.
49aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned NumParams;
50aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
51ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
52ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        Decl **Params, unsigned NumParams,
53ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                        SourceLocation RAngleLoc);
54aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
55aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
56ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  static TemplateParameterList *Create(ASTContext &C,
57ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation TemplateLoc,
58ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation LAngleLoc,
59ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       Decl **Params,
60ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       unsigned NumParams,
61ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                       SourceLocation RAngleLoc);
62aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
63aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// iterator - Iterates through the template parameters in this list.
64aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  typedef Decl** iterator;
65aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
66aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  /// const_iterator - Iterates through the template parameters in this list.
67aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  typedef Decl* const* const_iterator;
68aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
69aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator begin() { return reinterpret_cast<Decl **>(this + 1); }
70aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator begin() const {
71aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor    return reinterpret_cast<Decl * const *>(this + 1);
72aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
73aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  iterator end() { return begin() + NumParams; }
74aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  const_iterator end() const { return begin() + NumParams; }
75aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
76aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  unsigned size() const { return NumParams; }
77ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor
78f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  Decl* getParam(unsigned Idx) {
79f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
80f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor    return begin()[Idx];
81f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor  }
82f67875d5addf36b951ad37fb04509ab2b572c88aDouglas Gregor
8340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  const Decl* getParam(unsigned Idx) const {
8440808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    assert(Idx < size() && "Template parameter index out-of-range");
8540808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor    return begin()[Idx];
8640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor  }
8740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
8862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// \btief Returns the minimum number of arguments needed to form a
8962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template specialization. This may be fewer than the number of
9062cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  /// template parameters, if some of the parameters have default
910ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson  /// arguments or if there is a parameter pack.
9262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  unsigned getMinRequiredArguments() const;
9362cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
94ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getTemplateLoc() const { return TemplateLoc; }
95ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getLAngleLoc() const { return LAngleLoc; }
96ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  SourceLocation getRAngleLoc() const { return RAngleLoc; }
9762cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
9862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  SourceRange getSourceRange() const {
9962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor    return SourceRange(TemplateLoc, RAngleLoc);
10062cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor  }
101aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
102aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
103127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief Represents a template argument within a class template
104127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// specialization.
105127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgument {
106127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  union {
107127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    uintptr_t TypeOrValue;
108127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    struct {
109127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      char Value[sizeof(llvm::APSInt)];
110127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      void *Type;
111127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    } Integer;
112127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    struct {
113127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateArgument *Args;
114127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      unsigned NumArgs;
115127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      bool CopyArgs;
116127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    } Args;
117127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  };
118127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
119127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Location of the beginning of this template argument.
120127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation StartLoc;
121127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
122aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
123127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The type of template argument we're storing.
124127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  enum ArgKind {
125127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Null = 0,
126127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is a type. Its value is stored in the
127127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// TypeOrValue field.
128127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Type = 1,
129127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is a declaration
130127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Declaration = 2,
131127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is an integral value stored in an llvm::APSInt.
132127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Integral = 3,
133127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is a value- or type-dependent expression
134127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// stored in an Expr*.
135127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Expression = 4,
136127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
137127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// The template argument is actually a parameter pack. Arguments are stored
138127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// in the Args struct.
139127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Pack = 5
140127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  } Kind;
141127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
142127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct an empty, invalid template argument.
143127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
144127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
145127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct a template type argument.
146127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
147127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
148127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Loc;
149aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
150127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
151127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct a template argument that refers to a
152127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration, which is either an external declaration or a
153127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template declaration.
154127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
155127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // FIXME: Need to be sure we have the "canonical" declaration!
156127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    TypeOrValue = reinterpret_cast<uintptr_t>(D);
157127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Loc;
158aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
15916e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor
160127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct an integral constant template argument.
161127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
162127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                   QualType Type)
163127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : Kind(Integral) {
164127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    new (Integer.Value) llvm::APSInt(Value);
165127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Integer.Type = Type.getAsOpaquePtr();
166127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Loc;
167127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
168127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
169127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct a template argument that is an expression.
170127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
171127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// This form of template argument only occurs in template argument
172127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// lists used for dependent types and for expression; it will not
173127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// occur in a non-dependent, canonical template argument list.
174127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(Expr *E);
175127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
176127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Copy constructor for a template argument.
177127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
178127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind == Integral) {
179127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
180127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Integer.Type = Other.Integer.Type;
181127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    } else if (Kind == Pack) {
182127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Args.NumArgs = Other.Args.NumArgs;
183127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Args.Args = new TemplateArgument[Args.NumArgs];
184127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      for (unsigned I = 0; I != Args.NumArgs; ++I)
185127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        Args.Args[I] = Other.Args.Args[I];
186127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    }
187127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    else
188127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TypeOrValue = Other.TypeOrValue;
189127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Other.StartLoc;
190127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
191127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
192127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument& operator=(const TemplateArgument& Other) {
193127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // FIXME: Does not provide the strong guarantee for exception
194127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // safety.
195127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    using llvm::APSInt;
19616e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor
197127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // FIXME: Handle Packs
198127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind != Pack && "FIXME: Handle packs");
199127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Other.Kind != Pack && "FIXME: Handle packs");
20016e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor
201127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind == Other.Kind && Kind == Integral) {
202127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      // Copy integral values.
203127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      *this->getAsIntegral() = *Other.getAsIntegral();
204127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Integer.Type = Other.Integer.Type;
205127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    } else {
206127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      // Destroy the current integral value, if that's what we're holding.
207127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      if (Kind == Integral)
208127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getAsIntegral()->~APSInt();
209127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
210127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      Kind = Other.Kind;
211127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
212127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      if (Other.Kind == Integral) {
213127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
214127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        Integer.Type = Other.Integer.Type;
215127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      } else
216127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        TypeOrValue = Other.TypeOrValue;
217127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    }
218127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    StartLoc = Other.StartLoc;
219127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
220127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return *this;
221127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
222127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
223127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateArgument() {
224127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    using llvm::APSInt;
225127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
226127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind == Integral)
227127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      getAsIntegral()->~APSInt();
228127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    else if (Kind == Pack && Args.CopyArgs)
229127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      delete[] Args.Args;
230127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
231127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
232127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Return the kind of stored template argument.
233127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ArgKind getKind() const { return Kind; }
234127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
235127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template argument has no value.
236127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool isNull() const { return Kind == Null; }
237127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
238127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as a type.
239127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getAsType() const {
240127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Type)
241127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return QualType();
242127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
243127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return QualType::getFromOpaquePtr(
244127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      reinterpret_cast<void*>(TypeOrValue));
245127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
246127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
247127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as a declaration.
248127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Decl *getAsDecl() const {
249127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Declaration)
250127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return 0;
251127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return reinterpret_cast<Decl *>(TypeOrValue);
252127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
253127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
254127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as an integral value.
255127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::APSInt *getAsIntegral() {
256127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Integral)
257127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return 0;
258127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
259127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
260127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
261127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const llvm::APSInt *getAsIntegral() const {
262127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return const_cast<TemplateArgument*>(this)->getAsIntegral();
263127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
264127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
265127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the type of the integral value.
266127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getIntegralType() const {
267127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Integral)
268127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return QualType();
269127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
270127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return QualType::getFromOpaquePtr(Integer.Type);
271127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
272127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
273127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setIntegralType(QualType T) {
274127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind == Integral &&
275127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor           "Cannot set the integral type of a non-integral template argument");
276127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Integer.Type = T.getAsOpaquePtr();
27716e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor  };
27816e8be2ac532358d4e413fdfa2643b1876edda78Douglas Gregor
279127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument as an expression.
280127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getAsExpr() const {
281127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Kind != Expression)
282127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return 0;
283127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
284127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return reinterpret_cast<Expr *>(TypeOrValue);
285aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
286199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
287127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Iterator that traverses the elements of a template argument pack.
288127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  typedef const TemplateArgument * pack_iterator;
289127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
290127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Iterator referencing the first argument of a template argument
291127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// pack.
292127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  pack_iterator pack_begin() const {
293127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind == Pack);
294127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return Args.Args;
295fab9d67cebb87be968e7ae31a3b549a5279b5d51Douglas Gregor  }
296127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
297127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Iterator referencing one past the last argument of a template
298127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument pack.
299127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  pack_iterator pack_end() const {
300127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind == Pack);
301127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return Args.Args + Args.NumArgs;
302d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
303127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
304127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in the given template argument
305127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// pack.
306127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned pack_size() const {
307127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Kind == Pack);
308127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return Args.NumArgs;
309127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
310127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
311127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location where the template argument starts.
312127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getLocation() const { return StartLoc; }
313127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
314127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Construct a template argument pack.
315127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
316127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
317127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Used to insert TemplateArguments into FoldingSets.
318828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context) const {
319127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(Kind);
320127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    switch (Kind) {
321127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Null:
322127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
323127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
324127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Type:
325127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getAsType().Profile(ID);
326127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
327127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
328127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Declaration:
329828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor        ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
330127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
331127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
332127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Integral:
333127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getAsIntegral()->Profile(ID);
334127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        getIntegralType().Profile(ID);
335127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
336127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
337127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Expression:
338828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor        getAsExpr()->Profile(ID, Context, true);
339127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        break;
340127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
341127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      case Pack:
342127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        ID.AddInteger(Args.NumArgs);
343127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor        for (unsigned I = 0; I != Args.NumArgs; ++I)
344828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          Args.Args[I].Profile(ID, Context);
345127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    }
346aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
347aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
348aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
349127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A helper class for making template argument lists.
350127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentListBuilder {
351127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument *StructuredArgs;
352127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned MaxStructuredArgs;
353127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArgs;
354127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
355127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgument *FlatArgs;
356127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned MaxFlatArgs;
357127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArgs;
358127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
359127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool AddingToPack;
360127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned PackBeginIndex;
361127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
362aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
363127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
364127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                              unsigned NumTemplateArgs)
365127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
366127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NumStructuredArgs(0), FlatArgs(0),
367127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
368127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  AddingToPack(false), PackBeginIndex(0) { }
369127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
370127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Append(const TemplateArgument& Arg);
371127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void BeginPack();
372127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void EndPack();
373127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
374127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void ReleaseArgs();
375127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
376127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned flatSize() const {
377127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return NumFlatArgs;
378127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
379127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getFlatArguments() const {
380127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return FlatArgs;
381127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
382127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
383127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned structuredSize() const {
384127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat size.
385127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
386127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return flatSize();
387199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
388127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return NumStructuredArgs;
389d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
390127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getStructuredArguments() const {
391127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    // If we don't have any structured args, just reuse the flat args.
392127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (!StructuredArgs)
393127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return getFlatArguments();
394127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
395127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return StructuredArgs;
396aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
397aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor};
398aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
399127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief A template argument list.
400127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor///
401127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// FIXME: In the future, this class will be extended to support
402127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// variadic templates and member templates, which will make some of
403127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the function names below make more sense.
404127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateArgumentList {
405127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template argument list.
406127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ///
407127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// The integer value will be non-zero to indicate that this
408127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list does not own the pointer.
409127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
410127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
411127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The number of template arguments in this template
412127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument list.
413127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumFlatArguments;
414127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
415127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
416127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned NumStructuredArguments;
417127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
418aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregorpublic:
419127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateArgumentList(ASTContext &Context,
420127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateArgumentListBuilder &Builder,
421127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool TakeArgs);
422127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
423127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateArgumentList();
424127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
425127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
426127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &get(unsigned Idx) const {
427127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    assert(Idx < NumFlatArguments && "Invalid template argument index");
428127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getFlatArgumentList()[Idx];
429127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
430127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
431127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the template argument at a given index.
432127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
433127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
434127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in this
435127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template argument list.
436127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned size() const { return NumFlatArguments; }
437127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
438127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the number of template arguments in the
439127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// flattened template argument list.
440127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned flat_size() const { return NumFlatArguments; }
441127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
442127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the flattened template argument list.
443127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgument *getFlatArgumentList() const {
444127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return FlatArguments.getPointer();
445127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
446127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
447127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
448127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
449127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Templates
450127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
451aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
452127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
453127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// class, function, etc.). The TemplateDecl class stores the list of template
454127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and a reference to the templated scoped declaration: the
455127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// underlying AST node.
456127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateDecl : public NamedDecl {
457127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
458127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // This is probably never used.
459127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
460127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name)
461127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0)
462127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
463d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
464127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with the given name and parameters.
465127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Used when there is not templated element (tt-params, alias?).
466127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
467127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params)
468127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params)
469127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
470d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
471127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Construct a template decl with name, parameters, and templated element.
472127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
473127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               DeclarationName Name, TemplateParameterList *Params,
474127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor               NamedDecl *Decl)
475127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
476127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParams(Params) { }
477127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
478127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  ~TemplateDecl();
479d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
480127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the list of template parameters
481127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
482127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return TemplateParams;
483d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor  }
484d684b0027e16163c4bdba3e2f8bfadda7d62a0d3Douglas Gregor
485127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying, templated declaration.
486127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
487127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
488aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  // Implement isa/cast/dyncast/etc.
489aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const Decl *D) {
490127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
491aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  }
492127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateDecl *D) { return true; }
493127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D) { return true; }
494127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const ClassTemplateDecl *D) { return true; }
495aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
496aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
497127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
498127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NamedDecl *TemplatedDecl;
499127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParameterList* TemplateParams;
500127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
501127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
502127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// \brief Provides information about a function template specialization,
503127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// which is a FunctionDecl that has been explicitly specialization or
504127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// instantiated from a function template.
505127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
506127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
507127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The function template specialization that this structure
508127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// describes.
509127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *Function;
510127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
511127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The function template from which this function template
512127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization was generated.
5131fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  ///
5141fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// The bit will be 0 for an implicit instantiation, 1 for an explicit
5151fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// specialization.
5161fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  llvm::PointerIntPair<FunctionTemplateDecl *, 1> Template;
517127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
518127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The template arguments used to produce the function template
519127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// specialization from the function template.
520127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const TemplateArgumentList *TemplateArguments;
521127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
5221fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Retrieve the template from which this function was specialized.
5231fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
5241fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor
5251fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Determine whether this is an explicit specialization.
5261fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  bool isExplicitSpecialization() const { return Template.getInt(); }
5271fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor
5281fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// \brief Set whether this is an explicit specialization or an implicit
5291fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  /// instantiation.
5301fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  void setExplicitSpecialization(bool ES) {
5311fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor    Template.setInt(ES);
5321fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor  }
5331fd2dd145d9bcdf0b8d60a88e1795b6ae83656f5Douglas Gregor
534127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) {
535127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    Profile(ID, TemplateArguments->getFlatArgumentList(),
536828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            TemplateArguments->flat_size(),
537828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            Function->getASTContext());
538127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
539127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
540127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static void
541127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
542828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
543127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    ID.AddInteger(NumTemplateArgs);
544127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
545828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
546127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
547127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
548127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
549127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// Declaration of a template function.
550127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass FunctionTemplateDecl : public TemplateDecl {
551127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
552127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Data that is common to all of the declarations of a given
553127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
554127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  struct Common {
555127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// \brief The function template specializations for this function
556127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    /// template, including explicit specializations and instantiations.
557127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
5583e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  };
559127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
560127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief A pointer to the previous declaration (if this is a redeclaration)
561127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// or to the data that is common to all declarations of this function
562127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// template.
563127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
564127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
565127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieves the "common" pointer shared by all
566127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// (re-)declarations of the same function template. Calling this routine
567127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// may implicitly allocate memory for the common pointer.
568127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Common *getCommonPtr();
569127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
570127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
571127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       TemplateParameterList *Params, NamedDecl *Decl)
572127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
573127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev((Common*)0) { }
574127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
5753e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
576127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void Destroy(ASTContext &C);
577127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
578127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the underlying function declaration of the template.
579127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionDecl *getTemplatedDecl() const {
580127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return static_cast<FunctionDecl*>(TemplatedDecl);
5813e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
583127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the set of function template specializations of this
584127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// function template.
585127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
586127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return getCommonPtr()->Specializations;
5873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
588127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
589127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
590127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
591127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  const FunctionTemplateDecl *getPreviousDeclaration() const {
592127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
5933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
5943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
595127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the previous declaration of this function template, or
596127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// NULL if no such declaration exists.
597127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  FunctionTemplateDecl *getPreviousDeclaration() {
598127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
5993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
600127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
601127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the previous declaration of this function template.
602127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
603127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    if (Prev)
604127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      CommonOrPrev = Prev;
605127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
606127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
607b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual FunctionTemplateDecl *getCanonicalDecl();
608b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis
609127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Create a template function node.
610127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
611127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L,
612127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      DeclarationName Name,
613127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      TemplateParameterList *Params,
614127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      NamedDecl *Decl);
6153e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
616127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast support
617127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D)
618127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { return D->getKind() == FunctionTemplate; }
619127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const FunctionTemplateDecl *D)
620127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { return true; }
621127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
622d01b1da213aeb71fd40ff7fb78a194613cc1ece7Anders Carlsson
623127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
624127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor// Kinds of Template Parameters
625127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor//===----------------------------------------------------------------------===//
62640808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
627127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// The TemplateParmPosition class defines the position of a template parameter
628127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// within a template parameter list. Because template parameter can be listed
629127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// sequentially for out-of-line template members, each template parameter is
630127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// given a Depth - the nesting of template parameter scopes - and a Position -
631127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// the occurrence within the parameter list.
632127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// This class is inheritedly privately by different kinds of template
633127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// parameters and is not part of the Decl hierarchy. Just a facility.
634127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateParmPosition
635127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor{
636127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorprotected:
637127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: This should probably never be called, but it's here as
638127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition()
639127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(0), Position(0)
640127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { /* assert(0 && "Cannot create positionless template parameter"); */ }
6413e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
642127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateParmPosition(unsigned D, unsigned P)
643127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : Depth(D), Position(P)
644127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
6453e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
646127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
647127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // position? Maybe?
648127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Depth;
649127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned Position;
6503e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
651127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
652127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the nesting depth of the template parameter.
653127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getDepth() const { return Depth; }
6543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
655127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the position of the template parameter within its parameter list.
656127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getPosition() const { return Position; }
6570b9247f129401b4849682b2e2bcdea8fc977068aDouglas Gregor
658127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// Get the index of the template parameter within its parameter list.
659127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  unsigned getIndex() const { return Position; }
660127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor};
6613e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
662127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTypeParmDecl - Declaration of a template type parameter,
663127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
664127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
665127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<typename T> class vector;
666127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
667127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTypeParmDecl : public TypeDecl {
668127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declaration with
669127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If false, it was declared with the
670127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// 'class' keyword.
671127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool Typename : 1;
6723e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
673127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter inherited its
674127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// default argument.
675127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool InheritedDefault : 1;
6763e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
677127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this is a parameter pack.
678127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool ParameterPack : 1;
679127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
680127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The location of the default argument, if any.
681127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation DefaultArgumentLoc;
6823e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
683127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
684127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType DefaultArgument;
685127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
686127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
687127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                       bool Typename, QualType Type, bool ParameterPack)
688127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
689127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
690127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    TypeForDecl = Type.getTypePtr();
6913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
6923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
693127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
694127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
695127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      SourceLocation L, unsigned D, unsigned P,
696127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      IdentifierInfo *Id, bool Typename,
697127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                      bool ParameterPack);
698c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
699127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Whether this template type parameter was declared with
700127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// the 'typename' keyword. If not, it was declared with the 'class'
701127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// keyword.
702127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool wasDeclaredWithTypename() const { return Typename; }
703c971f8694661776ecdec2ccc33fbe0333eeaf191Douglas Gregor
704127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
705127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
706127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
707199d99192fbcca9f043596c40ead4afab4999dbaDouglas Gregor
708127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
709127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  QualType getDefaultArgument() const { return DefaultArgument; }
71040808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
711127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
712127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
71340808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
714127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determines whether the default argument was inherited
715127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// from a previous declaration of this template.
716127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool defaultArgumentWasInherited() const { return InheritedDefault; }
717f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor
718127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter, and
719127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// whether that default argument was inherited from another
720127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// declaration.
721127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
722127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          bool Inherited) {
723127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
724127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgumentLoc = DefArgLoc;
725127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    InheritedDefault = Inherited;
726f670c8cfa58b4c224eb8fb566130dc47844dd3deDouglas Gregor  }
72740808ce6ac04b102c3b56244a635d6b98eed6d97Douglas Gregor
728127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Returns whether this is a parameter pack.
729127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool isParameterPack() const { return ParameterPack; }
730fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
731127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
732127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
733127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == TemplateTypeParm;
7343e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
735127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTypeParmDecl *D) { return true; }
7363e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
7373e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
738127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
739127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "Size" in
740127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
741127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template<int Size> class array { };
742127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
743127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass NonTypeTemplateParmDecl
744127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public VarDecl, protected TemplateParmPosition {
745127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
746127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *DefaultArgument;
747127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
748127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
749127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                          unsigned P, IdentifierInfo *Id, QualType T,
750a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis                          DeclaratorInfo *DInfo)
751a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis    : VarDecl(NonTypeTemplateParm, DC, L, Id, T, DInfo, VarDecl::None),
752127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
753127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  { }
754127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
7551c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlssonpublic:
756127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static NonTypeTemplateParmDecl *
757127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
758a5d82000f7b173a0a5ce34dc8c09a03f98d9e439Argyrios Kyrtzidis         unsigned P, IdentifierInfo *Id, QualType T, DeclaratorInfo *DInfo);
7599ba41645892da0000fe8a7832b80208f44dafedaAnders Carlsson
760127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
761127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
762127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
763127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
764127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
765127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
766127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
767fb25052736439d72a557cddd41dfb927bcb3d3e5Anders Carlsson
768127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
769127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
770127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
771127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
772127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
773127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
774127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
775127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
776127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
7773b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
778127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
779127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
780127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
781127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == NonTypeTemplateParm;
7823b36b66a00b7d5bab71b486a54694f0ae397bddbAnders Carlsson  }
783127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
7841c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson};
7851c5976e5e933c0d74f7e04e8f907a93f5edbfec1Anders Carlsson
786127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// TemplateTemplateParmDecl - Declares a template template parameter,
787127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// e.g., "T" in
788127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @code
789127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// template <template <typename> class T> class container { };
790127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// @endcode
791127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// A template template parameter is a TemplateDecl because it defines the
792127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor/// name of a template and the template parameters allowable for substitution.
793127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorclass TemplateTemplateParmDecl
794127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  : public TemplateDecl, protected TemplateParmPosition {
7957e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
796127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief The default template argument, if any.
797127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *DefaultArgument;
7987e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
799127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
800127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           unsigned D, unsigned P,
801127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                           IdentifierInfo *Id, TemplateParameterList *Params)
802127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
803127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor      TemplateParmPosition(D, P), DefaultArgument(0)
804127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    { }
8057e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
806127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregorpublic:
807127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
808127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          SourceLocation L, unsigned D,
809127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          unsigned P, IdentifierInfo *Id,
810127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor                                          TemplateParameterList *Params);
8117e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
812127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getDepth;
813127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getPosition;
814127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  using TemplateParmPosition::getIndex;
815127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor
816127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Determine whether this template parameter has a default
817127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// argument.
818127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  bool hasDefaultArgument() const { return DefaultArgument; }
8197e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
820127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the default argument, if any.
821127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  Expr *getDefaultArgument() const { return DefaultArgument; }
8227e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
823127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Retrieve the location of the default argument, if any.
824127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  SourceLocation getDefaultArgumentLoc() const;
8257e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
826127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  /// \brief Set the default argument for this template parameter.
827127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  void setDefaultArgument(Expr *DefArg) {
828127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    DefaultArgument = DefArg;
829127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  }
8307e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
831127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  // Implement isa/cast/dyncast/etc.
832127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const Decl *D) {
833127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor    return D->getKind() == TemplateTemplateParm;
8347e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  }
835127102b5196ffe04bdb70fd553fe62c265ab10a9Douglas Gregor  static bool classof(const TemplateTemplateParmDecl *D) { return true; }
8367e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor};
8377e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor
838cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor// \brief Describes the kind of template specialization that a
839cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor// particular template specialization declaration represents.
840cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregorenum TemplateSpecializationKind {
841cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was formed from a template-id but
842cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// has not yet been declared, defined, or instantiated.
843cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_Undeclared = 0,
844cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was declared or defined by an
845c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// explicit specialization (C++ [temp.expl.spec]) or partial
846c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// specialization (C++ [temp.class.spec]).
847cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_ExplicitSpecialization,
848cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was implicitly instantiated from a
849cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// template. (C++ [temp.inst]).
850cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_ImplicitInstantiation,
851cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// This template specialization was instantiated from a template
852cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// due to an explicit instantiation request (C++ [temp.explicit]).
853cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TSK_ExplicitInstantiation
854cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor};
855cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
8563e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \brief Represents a class template specialization, which refers to
8573e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// a class template with a given set of template arguments.
8583e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8593e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Class template specializations represent both explicit
8603e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// specialization of class templates, as in the example below, and
8613e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// implicit instantiations of class templates.
8623e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8633e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \code
8643e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<typename T> class array;
8653e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor///
8663e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// template<>
8673e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// class array<bool> { }; // class template specialization array<bool>
8683e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// \endcode
8693e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateSpecializationDecl
8703e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  : public CXXRecordDecl, public llvm::FoldingSetNode {
87137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
87237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Structure that stores information about a class template
87337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization that was instantiated from a class template partial
87437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
87537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  struct SpecializedPartialSpecialization {
87637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The class template partial specialization from which this
87737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// class template specialization was instantiated.
87837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    ClassTemplatePartialSpecializationDecl *PartialSpecialization;
87937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
88037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// \brief The template argument list deduced for the class template
88137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    /// partial specialization itself.
88237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    TemplateArgumentList *TemplateArgs;
88337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  };
88437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
8853e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief The template that this specialization specializes
88637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
88737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate;
8883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
8897e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  /// \brief The template arguments used to describe this specialization.
8907e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  TemplateArgumentList TemplateArgs;
891cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
892cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief The kind of specialization this declaration refers to.
893cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// Really a value of type TemplateSpecializationKind.
894cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  unsigned SpecializationKind : 2;
895cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
896c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorprotected:
897c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
8987e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                  DeclContext *DC, SourceLocation L,
8993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                  ClassTemplateDecl *SpecializedTemplate,
9008e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  TemplateArgumentListBuilder &Builder,
9018e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                  ClassTemplateSpecializationDecl *PrevDecl);
9023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
9033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
9043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateSpecializationDecl *
9053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
9063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor         ClassTemplateDecl *SpecializedTemplate,
90791fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
908cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor         ClassTemplateSpecializationDecl *PrevDecl);
9093e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
91037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  virtual void Destroy(ASTContext& C);
91137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
9123e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the template that this specialization specializes.
91337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ClassTemplateDecl *getSpecializedTemplate() const;
9143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
91537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the template arguments of the class template
91637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization.
9177e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  const TemplateArgumentList &getTemplateArgs() const {
9187e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    return TemplateArgs;
9193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
9203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
921cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// \brief Determine the kind of specialization that this
922cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  /// declaration represents.
923cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  TemplateSpecializationKind getSpecializationKind() const {
924cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    return static_cast<TemplateSpecializationKind>(SpecializationKind);
925cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
926cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
927cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  void setSpecializationKind(TemplateSpecializationKind TSK) {
928cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    SpecializationKind = TSK;
929cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  }
930cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
93137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief If this class template specialization is an instantiation of
93237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a template (rather than an explicit specialization), return the
93337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// class template or class template partial specialization from which it
93437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// was instantiated.
93537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  llvm::PointerUnion<ClassTemplateDecl *,
93637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                     ClassTemplatePartialSpecializationDecl *>
93737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  getInstantiatedFrom() const {
93837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
93937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        getSpecializationKind() != TSK_ExplicitInstantiation)
94037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return (ClassTemplateDecl*)0;
94137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
94237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (SpecializedPartialSpecialization *PartialSpec
94337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
94437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return PartialSpec->PartialSpecialization;
94537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
94637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return const_cast<ClassTemplateDecl*>(
94737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                             SpecializedTemplate.get<ClassTemplateDecl*>());
94837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
94937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
95037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Retrieve the set of template arguments that should be used
95137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// to instantiate members of the class template or class template partial
95237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// specialization from which this class template specialization was
95337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiated.
95437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  ///
95537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \returns For a class template specialization instantiated from the primary
95637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template, this function will return the same template arguments as
95737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// getTemplateArgs(). For a class template specialization instantiated from
95837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// a class template partial specialization, this function will return the
95937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// deduced template arguments for the class template partial specialization
96037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// itself.
96137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  const TemplateArgumentList &getTemplateInstantiationArgs() const {
96237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    if (SpecializedPartialSpecialization *PartialSpec
96337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
96437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      return *PartialSpec->TemplateArgs;
96537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
96637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    return getTemplateArgs();
96737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
96837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
96937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// \brief Note that this class template specialization is actually an
97037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// instantiation of the given class template partial specialization whose
97137d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  /// template arguments have been deduced.
97237d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
97337d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor                          TemplateArgumentList *TemplateArgs) {
97437d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedPartialSpecialization *PS
97537d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor      = new (getASTContext()) SpecializedPartialSpecialization();
97637d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->PartialSpecialization = PartialSpec;
97737d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    PS->TemplateArgs = TemplateArgs;
97837d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor    SpecializedTemplate = PS;
97937d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor  }
98037d93e9252026d4fb836d9c05d0122a2d46e56beDouglas Gregor
981fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// \brief Sets the type of this specialization as it was written by
982fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  /// the user. This will be a class template specialization type.
983fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  void setTypeAsWritten(QualType T) {
984fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor    TypeForDecl = T.getTypePtr();
985fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor  }
986fc705b84347e6fb4746a1a7e26949f64c2f2f358Douglas Gregor
987c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
988828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor    Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
989828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor            getASTContext());
990c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
991c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
9923e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static void
9933e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
994828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor          unsigned NumTemplateArgs, ASTContext &Context) {
9950ceffb51b28b09db67404058c642dcb1f877f6e8Anders Carlsson    ID.AddInteger(NumTemplateArgs);
9963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
997828e226ab7ed08b3eb766549e9d3306432137460Douglas Gregor      TemplateArgs[Arg].Profile(ID, Context);
9983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
9993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const Decl *D) {
1001c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return D->getKind() == ClassTemplateSpecialization ||
1002c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor           D->getKind() == ClassTemplatePartialSpecialization;
10033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
10043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10053e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateSpecializationDecl *) {
10063e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return true;
10073e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
1008c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1009c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1010c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1011c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1012c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor};
1013c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1014c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorclass ClassTemplatePartialSpecializationDecl
1015c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  : public ClassTemplateSpecializationDecl
1016c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor{
1017c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// \brief The list of template parameters
1018c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList* TemplateParams;
1019c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1020c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  ClassTemplatePartialSpecializationDecl(ASTContext &Context,
1021c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         DeclContext *DC, SourceLocation L,
1022c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         TemplateParameterList *Params,
1023c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor                                         ClassTemplateDecl *SpecializedTemplate,
10248e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                         TemplateArgumentListBuilder &Builder,
10258e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                               ClassTemplatePartialSpecializationDecl *PrevDecl)
10268e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor    : ClassTemplateSpecializationDecl(Context,
10278e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      ClassTemplatePartialSpecialization,
10288e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      DC, L, SpecializedTemplate, Builder,
10298e9e9ef5348bce1a8f0741a5684fac3de9701c28Douglas Gregor                                      PrevDecl),
1030c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      TemplateParams(Params) { }
1031c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1032c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregorpublic:
1033c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static ClassTemplatePartialSpecializationDecl *
1034c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
1035c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         TemplateParameterList *Params,
1036c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplateDecl *SpecializedTemplate,
103791fdf6f576b91f023c3bebb0d3786aab555cb3c5Anders Carlsson         TemplateArgumentListBuilder &Builder,
1038c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor         ClassTemplatePartialSpecializationDecl *PrevDecl);
1039c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1040c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// Get the list of template parameters
1041c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  TemplateParameterList *getTemplateParameters() const {
1042c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return TemplateParams;
1043c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1044c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1045c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  // FIXME: Add Profile support!
1046c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1047c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const Decl *D) {
1048c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return D->getKind() == ClassTemplatePartialSpecialization;
1049c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1050c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1051c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  static bool classof(const ClassTemplatePartialSpecializationDecl *) {
1052c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return true;
1053c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
10543e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
10553e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10563e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor/// Declaration of a class template.
10573e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorclass ClassTemplateDecl : public TemplateDecl {
10583e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorprotected:
10595953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Data that is common to all of the declarations of a given
10605953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// class template.
10615953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  struct Common {
1062e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    Common() : InstantiatedFromMember(0) {}
1063e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
10645953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// \brief The class template specializations for this class
10655953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    /// template, including explicit specializations and instantiations.
10665953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
10677da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1068c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// \brief The class template partial specializations for this class
1069c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    /// template.
1070c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>
1071c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor      PartialSpecializations;
1072c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
10737da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    /// \brief The injected-class-name type for this class template.
10747da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    QualType InjectedClassNameType;
1075e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1076e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// \brief The templated member class from which this was most
1077e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    /// directly instantiated (or null).
1078e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    ClassTemplateDecl *InstantiatedFromMember;
10795953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  };
10805953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
10817532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor  /// \brief Previous declaration of this class template.
10825953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ClassTemplateDecl *PreviousDeclaration;
10835953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
10845953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// \brief Pointer to the data that is common to all of the
10855953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// declarations of this class template.
10865953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ///
10875953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// The first declaration of a class template (e.g., the declaration
10885953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// with no "previous declaration") owns this pointer.
10895953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  Common *CommonPtr;
10905953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
10913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
10925953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    TemplateParameterList *Params, NamedDecl *Decl,
10935953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                    ClassTemplateDecl *PrevDecl, Common *CommonPtr)
10945953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    : TemplateDecl(ClassTemplate, DC, L, Name, Params, Decl),
10955953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor      PreviousDeclaration(PrevDecl), CommonPtr(CommonPtr) { }
10963e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10975953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  ~ClassTemplateDecl();
10983e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
10993e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregorpublic:
11003e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// Get the underlying class declarations of the template.
11013e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  CXXRecordDecl *getTemplatedDecl() const {
11023e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor    return static_cast<CXXRecordDecl *>(TemplatedDecl);
11033e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11043e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11057da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \brief Retrieve the previous declaration of this template.
11067da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ClassTemplateDecl *getPreviousDeclaration() const {
11077da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor    return PreviousDeclaration;
11087da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  }
1109b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis
1110b57a4fe73b8227c0dba651818b8495dfca61e530Argyrios Kyrtzidis  virtual ClassTemplateDecl *getCanonicalDecl();
11117da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
11125953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  /// Create a class template node.
11133e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
11143e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   SourceLocation L,
11153e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   DeclarationName Name,
11163e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor                                   TemplateParameterList *Params,
11175953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   NamedDecl *Decl,
11185953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor                                   ClassTemplateDecl *PrevDecl);
11193e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
11203e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  /// \brief Retrieve the set of specializations of this class template.
11213e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
11225953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor    return CommonPtr->Specializations;
11233e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  }
11243e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1125c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// \brief Retrieve the set of partial specializations of this class
1126c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  /// template.
1127c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
1128c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  getPartialSpecializations() {
1129c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor    return CommonPtr->PartialSpecializations;
1130c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor  }
1131c8ab2563ac8f7dcc4fdc518b5cc7015ecbb2f003Douglas Gregor
1132b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief Find a class template partial specialization with the given
1133b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// type T.
1134b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1135b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \brief A dependent type that names a specialization of this class
1136b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// template.
1137b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ///
1138b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// \returns the class template partial specialization that exactly matches
1139b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  /// the type \p T, or NULL if no such partial specialization exists.
1140b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor  ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
1141b88e888404ad0a2bdd9bfae457e8530bb38a87c5Douglas Gregor
11427da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \brief Retrieve the type of the injected-class-name for this
11437da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// class template.
11447da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
11457da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// The injected-class-name for a class template \c X is \c
11467da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// X<template-args>, where \c template-args is formed from the
11477da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template arguments that correspond to the template parameters of
11487da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \c X. For example:
11497da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///
11507da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \code
11517da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// template<typename T, int N>
11527da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// struct array {
11537da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  ///   typedef array this_type; // "array" is equivalent to "array<T, N>"
11547da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// };
11557da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  /// \endcode
11567da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor  QualType getInjectedClassNameType(ASTContext &Context);
11577da97d0f31e1ec16998d3de2cfd2e88fe3736673Douglas Gregor
1158e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \brief Retrieve the member class template that this class template was
1159e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// derived from.
1160e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1161e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// This routine will return non-NULL for templated member classes of
1162e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// class templates.  For example, given:
1163e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1164e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \code
1165e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// template <typename T>
1166e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// struct X {
1167e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///   template <typename U> struct A {};
1168e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// };
1169e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \endcode
1170e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1171e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
1172e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
1173e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// return X<int>::A<U>, a TemplateClassDecl (whose parent is again
1174e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<int>) for which getInstantiatedFromMemberTemplate() will return
1175e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// X<T>::A<U>, a TemplateClassDecl (whose parent is X<T>, also a TCD).
1176e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ///
1177e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  /// \returns null if this is not an instantiation of a member class template.
1178e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
1179e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    return CommonPtr->InstantiatedFromMember;
1180e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1181e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
1182e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  void setInstantiatedFromMemberTemplate(ClassTemplateDecl *CTD) {
1183e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    assert(!CommonPtr->InstantiatedFromMember);
1184e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall    CommonPtr->InstantiatedFromMember = CTD;
1185e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall  }
1186e29ba20148e9b7835ad463b39cd4ee9223eafbbfJohn McCall
11873e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  // Implement isa/cast/dyncast support
11883e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const Decl *D)
11893e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return D->getKind() == ClassTemplate; }
11903e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  static bool classof(const ClassTemplateDecl *D)
11913e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor  { return true; }
11925953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor
11935953d8b37f92f0cf548941f617c9b0a7703df33bDouglas Gregor  virtual void Destroy(ASTContext& C);
11943e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor};
11953e00bad490f1bae8a2c60f934e7eb5dbb9752c5dDouglas Gregor
1196e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// Implementation of inline functions that require the template declarations
1197e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregorinline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
1198e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor  : Function(FTD) { }
1199e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor
1200aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor} /* end of namespace clang */
1201aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor
1202aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor#endif
1203