1275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
2275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//
3275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//                     The LLVM Compiler Infrastructure
4275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//
5275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall// This file is distributed under the University of Illinois Open Source
6275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall// License. See LICENSE.TXT for details.
7275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//
8275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//===----------------------------------------------------------------------===//
9275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//
10275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//  This file provides definitions which are common for all kinds of
11275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//  template representation.
12275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//
13275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall//===----------------------------------------------------------------------===//
14275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
15275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
16275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall#define LLVM_CLANG_AST_TEMPLATEBASE_H
17275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
18aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar#include "clang/AST/TemplateName.h"
1930a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/AST/Type.h"
20275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall#include "llvm/ADT/APSInt.h"
21d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall#include "llvm/ADT/SmallVector.h"
22aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar#include "llvm/Support/Compiler.h"
23833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall#include "llvm/Support/ErrorHandling.h"
24275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
25275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCallnamespace llvm {
26275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  class FoldingSetNodeID;
27275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall}
28275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
29275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCallnamespace clang {
30275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
31a933319ebf754396623165f9dc0a29c2a48879f5Douglas Gregorclass DiagnosticBuilder;
32275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCallclass Expr;
3387dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregorstruct PrintingPolicy;
34a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCallclass TypeSourceInfo;
35d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedmanclass ValueDecl;
36275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief Represents a template argument.
38275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCallclass TemplateArgument {
39275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCallpublic:
402bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor  /// \brief The kind of template argument we're storing.
41275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  enum ArgKind {
42788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    /// \brief Represents an empty template argument, e.g., one that has not
43788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    /// been deduced.
44275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall    Null = 0,
45d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    /// The template argument is a type.
46788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    Type,
47d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    /// The template argument is a declaration that was provided for a pointer,
48d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    /// reference, or pointer to member non-type template parameter.
49788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    Declaration,
50d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    /// The template argument is a null pointer or null pointer to member that
51d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    /// was provided for a non-type template parameter.
52d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    NullPtr,
53788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    /// The template argument is an integral value stored in an llvm::APSInt
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// that was provided for an integral non-type template parameter.
55788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    Integral,
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// The template argument is a template name that was provided for a
57788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    /// template template parameter.
58788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    Template,
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// The template argument is a pack expansion of a template name that was
60a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor    /// provided for a template template parameter.
61a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor    TemplateExpansion,
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// The template argument is an expression, and we've not resolved it to one
63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// of the other forms yet, either because it's dependent or because we're
64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// representing a non-canonical template argument (for instance, in a
65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// TemplateSpecializationType). Also used to represent a non-dependent
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// __uuidof expression (a Microsoft extension).
67788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    Expression,
68275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall    /// The template argument is actually a parameter pack. Arguments are stored
69275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall    /// in the Args struct.
70788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    Pack
712bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor  };
722bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor
732bde8273eb5730324f823945d0c2389badf325e6Douglas Gregorprivate:
742bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor  /// \brief The kind of template argument we're storing.
75275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
76e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct DA {
77c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    unsigned Kind;
78e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    bool ForRefParam;
79c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    ValueDecl *D;
80e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
81e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct I {
82c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    unsigned Kind;
83e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    // We store a decomposed APSInt with the data allocated by ASTContext if
84e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    // BitWidth > 64. The memory may be shared between multiple
85e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    // TemplateArgument instances.
86c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    unsigned BitWidth : 31;
87c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    unsigned IsUnsigned : 1;
88e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    union {
89e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher      uint64_t VAL;          ///< Used to store the <= 64 bits integer value.
90e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher      const uint64_t *pVal;  ///< Used to store the >64 bits integer value.
91e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    };
92e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    void *Type;
93e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
94e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct A {
95c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    unsigned Kind;
96e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned NumArgs;
97c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    const TemplateArgument *Args;
98e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
99e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct TA {
100c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    unsigned Kind;
101e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned NumExpansions;
102c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    void *Name;
103c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  };
104c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  struct TV {
105c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    unsigned Kind;
106c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    uintptr_t V;
107e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
1082bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor  union {
109e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct DA DeclArg;
110e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct I Integer;
111e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct A Args;
112e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct TA TemplateArg;
113c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    struct TV TypeOrValue;
1142bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor  };
1152bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor
116e2e1fa27e2533410f744137b0db1bc9491543392David Blaikie  TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION;
1172be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor
1182bde8273eb5730324f823945d0c2389badf325e6Douglas Gregorpublic:
119275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Construct an empty, invalid template argument.
120c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  TemplateArgument() {
121c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    TypeOrValue.Kind = Null;
122c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    TypeOrValue.V = 0;
123c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  }
124275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
125275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Construct a template type argument.
126c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  TemplateArgument(QualType T, bool isNullPtr = false) {
127c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
128c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
129275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
130275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
131275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Construct a template argument that refers to a
132275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// declaration, which is either an external declaration or a
133275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// template declaration.
134c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  TemplateArgument(ValueDecl *D, bool ForRefParam) {
135d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    assert(D && "Expected decl");
136c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    DeclArg.Kind = Declaration;
137d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    DeclArg.D = D;
138d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    DeclArg.ForRefParam = ForRefParam;
139275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
140275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
141855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer  /// \brief Construct an integral constant template argument. The memory to
142855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer  /// store the value is allocated with Ctx.
143855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer  TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
144855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer
145855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer  /// \brief Construct an integral constant template argument with the same
146855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer  /// value as Other but a different type.
147c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  TemplateArgument(const TemplateArgument &Other, QualType Type) {
148855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer    Integer = Other.Integer;
149275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall    Integer.Type = Type.getAsOpaquePtr();
150275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
151275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
1522be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// \brief Construct a template argument that is a template.
153788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  ///
154788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  /// This form of template argument is generally used for template template
155788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  /// parameters. However, the template name could be a dependent template
156788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  /// name that ends up being instantiated to a function template whose address
157788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  /// is taken.
158ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor  ///
159ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor  /// \param Name The template name.
160c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  TemplateArgument(TemplateName Name) {
161c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    TemplateArg.Kind = Template;
1622be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor    TemplateArg.Name = Name.getAsVoidPointer();
1632be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor    TemplateArg.NumExpansions = 0;
164788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
1652be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor
1662be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// \brief Construct a template argument that is a template pack expansion.
1672be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  ///
1682be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// This form of template argument is generally used for template template
1692be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// parameters. However, the template name could be a dependent template
1702be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// name that ends up being instantiated to a function template whose address
1712be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// is taken.
1722be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  ///
1732be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// \param Name The template name.
1742be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  ///
1752be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// \param NumExpansions The number of expansions that will be generated by
1762be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// instantiating
177c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
178c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    TemplateArg.Kind = TemplateExpansion;
1792be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor    TemplateArg.Name = Name.getAsVoidPointer();
1802be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor    if (NumExpansions)
1812be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor      TemplateArg.NumExpansions = *NumExpansions + 1;
1822be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor    else
1832be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor      TemplateArg.NumExpansions = 0;
1842be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  }
1852be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor
186275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Construct a template argument that is an expression.
187275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  ///
188275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// This form of template argument only occurs in template argument
189275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// lists used for dependent types and for expression; it will not
190275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// occur in a non-dependent, canonical template argument list.
191c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  TemplateArgument(Expr *E) {
192c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    TypeOrValue.Kind = Expression;
193c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
194833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
195275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
196910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// \brief Construct a template argument that is a template argument pack.
197910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  ///
198910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// We assume that storage for the template arguments provided
199910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  /// outlives the TemplateArgument itself.
200c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) {
201c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    this->Args.Kind = Pack;
202910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    this->Args.Args = Args;
203910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor    this->Args.NumArgs = NumArgs;
204910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor  }
205910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor
206d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  static TemplateArgument getEmptyPack() {
2076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return TemplateArgument((TemplateArgument*)nullptr, 0);
208d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  }
209d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman
210203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor  /// \brief Create a new template argument pack by copying the given set of
211203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor  /// template arguments.
212203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor  static TemplateArgument CreatePackCopy(ASTContext &Context,
213203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor                                         const TemplateArgument *Args,
214203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor                                         unsigned NumArgs);
215203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor
216275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Return the kind of stored template argument.
217c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
218275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
219275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Determine whether this template argument has no value.
220c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman  bool isNull() const { return getKind() == Null; }
221275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
222bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  /// \brief Whether this template argument is dependent on a template
223561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// parameter such that its result can change from one instantiation to
224561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// another.
225bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor  bool isDependent() const;
226bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor
227561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// \brief Whether this template argument is dependent on a template
228561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  /// parameter.
229561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor  bool isInstantiationDependent() const;
230561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
231d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// \brief Whether this template argument contains an unexpanded
232d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  /// parameter pack.
233d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor  bool containsUnexpandedParameterPack() const;
234d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor
2358491ffe86c50241b47c6d7ef8cd9ee00f5e675daDouglas Gregor  /// \brief Determine whether this template argument is a pack expansion.
2368491ffe86c50241b47c6d7ef8cd9ee00f5e675daDouglas Gregor  bool isPackExpansion() const;
2378491ffe86c50241b47c6d7ef8cd9ee00f5e675daDouglas Gregor
238d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  /// \brief Retrieve the type for a type template argument.
239275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  QualType getAsType() const {
240c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Type && "Unexpected kind");
241c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
242275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
243275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
244d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  /// \brief Retrieve the declaration for a declaration non-type
245d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  /// template argument.
246d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  ValueDecl *getAsDecl() const {
247c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Declaration && "Unexpected kind");
248d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    return DeclArg.D;
249d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  }
250d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman
251d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  /// \brief Retrieve whether a declaration is binding to a
252d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  /// reference parameter in a declaration non-type template argument.
253d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  bool isDeclForReferenceParam() const {
254c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Declaration && "Unexpected kind");
255d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    return DeclArg.ForRefParam;
256275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
257275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
258d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  /// \brief Retrieve the type for null non-type template argument.
259d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  QualType getNullPtrType() const {
260c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == NullPtr && "Unexpected kind");
261c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
262d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  }
263d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman
264d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  /// \brief Retrieve the template name for a template name argument.
265788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  TemplateName getAsTemplate() const {
266c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Template && "Unexpected kind");
2672be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor    return TemplateName::getFromVoidPointer(TemplateArg.Name);
268788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
269a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor
270a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor  /// \brief Retrieve the template argument as a template name; if the argument
271a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor  /// is a pack expansion, return the pattern as a template name.
272a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor  TemplateName getAsTemplateOrTemplatePattern() const {
273c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert((getKind() == Template || getKind() == TemplateExpansion) &&
274d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman           "Unexpected kind");
275a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor
2762be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor    return TemplateName::getFromVoidPointer(TemplateArg.Name);
277a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor  }
278a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor
2792be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// \brief Retrieve the number of expansions that a template template argument
2802be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor  /// expansion will produce, if known.
281dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie  Optional<unsigned> getNumTemplateExpansions() const;
2822be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor
283275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Retrieve the template argument as an integral value.
284855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer  // FIXME: Provide a way to read the integral data without copying the value.
285855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer  llvm::APSInt getAsIntegral() const {
286c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Integral && "Unexpected kind");
287b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer    using namespace llvm;
288855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer    if (Integer.BitWidth <= 64)
289b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer      return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
290b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer
291b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer    unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
292b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer    return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
293b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer                  Integer.IsUnsigned);
294275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
295275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
296275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Retrieve the type of the integral value.
297275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  QualType getIntegralType() const {
298c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Integral && "Unexpected kind");
299275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall    return QualType::getFromOpaquePtr(Integer.Type);
300275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
301275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
302275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  void setIntegralType(QualType T) {
303c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Integral && "Unexpected kind");
304275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall    Integer.Type = T.getAsOpaquePtr();
3057177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar  }
306275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
307275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Retrieve the template argument as an expression.
308275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  Expr *getAsExpr() const {
309c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Expression && "Unexpected kind");
310c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    return reinterpret_cast<Expr *>(TypeOrValue.V);
311275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
312275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
313275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Iterator that traverses the elements of a template argument pack.
314275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  typedef const TemplateArgument * pack_iterator;
315275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
316275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Iterator referencing the first argument of a template argument
317275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// pack.
318275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  pack_iterator pack_begin() const {
319c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Pack);
320275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall    return Args.Args;
321275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
322275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
323275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Iterator referencing one past the last argument of a template
324275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// argument pack.
325275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  pack_iterator pack_end() const {
326c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Pack);
327275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall    return Args.Args + Args.NumArgs;
328275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
329275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
330275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief The number of template arguments in the given template argument
331275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// pack.
332275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  unsigned pack_size() const {
333c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Pack);
334275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall    return Args.NumArgs;
335275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  }
336275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
3375a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  /// \brief Return the array of arguments in this template argument pack.
338ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ArrayRef<TemplateArgument> getPackAsArray() const {
339c0afea9495ba535ac5de07c32b68a5559622737eEli Friedman    assert(getKind() == Pack);
340ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
3415a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall  }
3425a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall
343efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett  /// \brief Determines whether two template arguments are superficially the
34433500955d731c73717af52088b7fc0e7a85681e7John McCall  /// same.
34533500955d731c73717af52088b7fc0e7a85681e7John McCall  bool structurallyEquals(const TemplateArgument &Other) const;
34633500955d731c73717af52088b7fc0e7a85681e7John McCall
347efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett  /// \brief When the template argument is a pack expansion, returns
348e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  /// the pattern of the pack expansion.
349e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor  TemplateArgument getPackExpansionPattern() const;
350e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor
35187dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor  /// \brief Print this template argument to the given output stream.
3528cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner  void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
35387dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor
354275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall  /// \brief Used to insert TemplateArguments into FoldingSets.
3554ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
356275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall};
357275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
358833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall/// Location information for a TemplateArgument.
359833ca991c1bfc967f0995974ca86f66ba1f666b5John McCallstruct TemplateArgumentLocInfo {
360833ca991c1bfc967f0995974ca86f66ba1f666b5John McCallprivate:
361e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
362e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  struct T {
363e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    // FIXME: We'd like to just use the qualifier in the TemplateName,
364e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    // but template arguments get canonicalized too quickly.
365e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    NestedNameSpecifier *Qualifier;
366e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    void *QualifierLocData;
367e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned TemplateNameLoc;
368e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    unsigned EllipsisLoc;
369e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher  };
370e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher
371828bff2079b6a91ecd7ed5b842c59527d7682789John McCall  union {
372e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher    struct T Template;
373828bff2079b6a91ecd7ed5b842c59527d7682789John McCall    Expr *Expression;
374a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    TypeSourceInfo *Declarator;
375828bff2079b6a91ecd7ed5b842c59527d7682789John McCall  };
376833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
377833ca991c1bfc967f0995974ca86f66ba1f666b5John McCallpublic:
378b0ddf3aeb2f119cac42468b029584e8839b354ccDouglas Gregor  TemplateArgumentLocInfo();
3798de39b431d3775cd46584080beec3a75d019bd28Douglas Gregor
3806939fff69a3dfff2552261a1d7f1f609380fe6b0Douglas Gregor  TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
3818de39b431d3775cd46584080beec3a75d019bd28Douglas Gregor
3826939fff69a3dfff2552261a1d7f1f609380fe6b0Douglas Gregor  TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
383788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor
384b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor  TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
385ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor                          SourceLocation TemplateNameLoc,
386ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor                          SourceLocation EllipsisLoc)
387788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  {
388b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor    Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
389b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor    Template.QualifierLocData = QualifierLoc.getOpaqueData();
390788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
391ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor    Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
392788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
393833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
394a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *getAsTypeSourceInfo() const {
395828bff2079b6a91ecd7ed5b842c59527d7682789John McCall    return Declarator;
396833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
397833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
398833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  Expr *getAsExpr() const {
399828bff2079b6a91ecd7ed5b842c59527d7682789John McCall    return Expression;
400833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
401833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
402b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
403b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor    return NestedNameSpecifierLoc(Template.Qualifier,
404b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor                                  Template.QualifierLocData);
405788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
406788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor
407788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  SourceLocation getTemplateNameLoc() const {
408788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
409788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
410ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor
411ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor  SourceLocation getTemplateEllipsisLoc() const {
412ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor    return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
413ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor  }
414833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall};
415833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
416833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall/// Location wrapper for a TemplateArgument.  TemplateArgument is to
417833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall/// TemplateArgumentLoc as Type is to TypeLoc.
418833ca991c1bfc967f0995974ca86f66ba1f666b5John McCallclass TemplateArgumentLoc {
419833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgument Argument;
420833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLocInfo LocInfo;
421833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
422828bff2079b6a91ecd7ed5b842c59527d7682789John McCallpublic:
423828bff2079b6a91ecd7ed5b842c59527d7682789John McCall  TemplateArgumentLoc() {}
424828bff2079b6a91ecd7ed5b842c59527d7682789John McCall
425833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc(const TemplateArgument &Argument,
426833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall                      TemplateArgumentLocInfo Opaque)
427833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    : Argument(Argument), LocInfo(Opaque) {
428833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
429833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
430a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
431a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    : Argument(Argument), LocInfo(TInfo) {
432833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    assert(Argument.getKind() == TemplateArgument::Type);
433833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
434833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
435833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
436833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    : Argument(Argument), LocInfo(E) {
437833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    assert(Argument.getKind() == TemplateArgument::Expression);
438833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
439833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
440788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  TemplateArgumentLoc(const TemplateArgument &Argument,
441b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor                      NestedNameSpecifierLoc QualifierLoc,
442ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor                      SourceLocation TemplateNameLoc,
443ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor                      SourceLocation EllipsisLoc = SourceLocation())
444b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor    : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
445a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor    assert(Argument.getKind() == TemplateArgument::Template ||
446a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor           Argument.getKind() == TemplateArgument::TemplateExpansion);
447788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
448788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor
449788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  /// \brief - Fetches the primary location of the argument.
450828bff2079b6a91ecd7ed5b842c59527d7682789John McCall  SourceLocation getLocation() const {
451a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor    if (Argument.getKind() == TemplateArgument::Template ||
452a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor        Argument.getKind() == TemplateArgument::TemplateExpansion)
453788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor      return getTemplateNameLoc();
454788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor
455828bff2079b6a91ecd7ed5b842c59527d7682789John McCall    return getSourceRange().getBegin();
456833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
457833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
458828bff2079b6a91ecd7ed5b842c59527d7682789John McCall  /// \brief - Fetches the full source range of the argument.
459aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar  SourceRange getSourceRange() const LLVM_READONLY;
460833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
461833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  const TemplateArgument &getArgument() const {
462833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return Argument;
463833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
464833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
465833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  TemplateArgumentLocInfo getLocInfo() const {
466833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return LocInfo;
467833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
468833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
469a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall  TypeSourceInfo *getTypeSourceInfo() const {
470833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    assert(Argument.getKind() == TemplateArgument::Type);
471a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall    return LocInfo.getAsTypeSourceInfo();
472833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
473833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
474833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  Expr *getSourceExpression() const {
475833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    assert(Argument.getKind() == TemplateArgument::Expression);
476828bff2079b6a91ecd7ed5b842c59527d7682789John McCall    return LocInfo.getAsExpr();
477828bff2079b6a91ecd7ed5b842c59527d7682789John McCall  }
478828bff2079b6a91ecd7ed5b842c59527d7682789John McCall
479828bff2079b6a91ecd7ed5b842c59527d7682789John McCall  Expr *getSourceDeclExpression() const {
480828bff2079b6a91ecd7ed5b842c59527d7682789John McCall    assert(Argument.getKind() == TemplateArgument::Declaration);
481833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall    return LocInfo.getAsExpr();
482833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  }
483d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman
484d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  Expr *getSourceNullPtrExpression() const {
485d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    assert(Argument.getKind() == TemplateArgument::NullPtr);
486d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    return LocInfo.getAsExpr();
487d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  }
488d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman
489d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  Expr *getSourceIntegralExpression() const {
490d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    assert(Argument.getKind() == TemplateArgument::Integral);
491d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman    return LocInfo.getAsExpr();
492d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman  }
493d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman
494b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
495a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor    assert(Argument.getKind() == TemplateArgument::Template ||
496a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor           Argument.getKind() == TemplateArgument::TemplateExpansion);
497b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor    return LocInfo.getTemplateQualifierLoc();
498788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
499788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor
500788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  SourceLocation getTemplateNameLoc() const {
501a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor    assert(Argument.getKind() == TemplateArgument::Template ||
502a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor           Argument.getKind() == TemplateArgument::TemplateExpansion);
503788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor    return LocInfo.getTemplateNameLoc();
504788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor  }
5058491ffe86c50241b47c6d7ef8cd9ee00f5e675daDouglas Gregor
506ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor  SourceLocation getTemplateEllipsisLoc() const {
507a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor    assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
508ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor    return LocInfo.getTemplateEllipsisLoc();
509ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor  }
510833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall};
511833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
512d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall/// A convenient class for passing around template argument
513d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall/// information.  Designed to be passed by reference.
514d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallclass TemplateArgumentListInfo {
515686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<TemplateArgumentLoc, 8> Arguments;
516d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  SourceLocation LAngleLoc;
517d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  SourceLocation RAngleLoc;
518d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
51971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
52071a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  // instead.
52171a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  void* operator new(size_t bytes, ASTContext& C);
52271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis
523d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallpublic:
524d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  TemplateArgumentListInfo() {}
525d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
526d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  TemplateArgumentListInfo(SourceLocation LAngleLoc,
527d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                           SourceLocation RAngleLoc)
528d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall    : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
529d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
530d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  SourceLocation getLAngleLoc() const { return LAngleLoc; }
531d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  SourceLocation getRAngleLoc() const { return RAngleLoc; }
532d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
533d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
534d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
535d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
536d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  unsigned size() const { return Arguments.size(); }
537d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
538d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  const TemplateArgumentLoc *getArgumentArray() const {
539d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall    return Arguments.data();
540d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  }
541d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
542d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  const TemplateArgumentLoc &operator[](unsigned I) const {
543d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall    return Arguments[I];
544d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  }
545d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
546ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  TemplateArgumentLoc &operator[](unsigned I) {
547ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return Arguments[I];
548ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  }
549ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
550d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  void addArgument(const TemplateArgumentLoc &Loc) {
551d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall    Arguments.push_back(Loc);
552d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  }
553d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall};
554d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
55571a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis/// \brief Represents an explicit template argument list in C++, e.g.,
55671a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis/// the "<int>" in "sort<int>".
55771a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis/// This is safe to be used inside an AST node, in contrast with
55871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis/// TemplateArgumentListInfo.
55971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidisstruct ASTTemplateArgumentListInfo {
56097f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith  /// \brief The source location of the left angle bracket ('<').
56171a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  SourceLocation LAngleLoc;
56271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis
56397f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith  /// \brief The source location of the right angle bracket ('>').
56471a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  SourceLocation RAngleLoc;
56571a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis
56697f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith  union {
56797f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith    /// \brief The number of template arguments in TemplateArgs.
56897f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith    /// The actual template arguments (if any) are stored after the
56997f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith    /// ExplicitTemplateArgumentList structure.
57097f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith    unsigned NumTemplateArgs;
57197f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith
57297f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith    /// Force ASTTemplateArgumentListInfo to the right alignment
57397f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith    /// for the following array of TemplateArgumentLocs.
574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    llvm::AlignedCharArray<
575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        llvm::AlignOf<TemplateArgumentLoc>::Alignment, 1> Aligner;
57697f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith  };
57797f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith
57871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  /// \brief Retrieve the template arguments
57971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  TemplateArgumentLoc *getTemplateArgs() {
58071a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis    return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
58171a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  }
58271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis
58371a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  /// \brief Retrieve the template arguments
58471a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  const TemplateArgumentLoc *getTemplateArgs() const {
58571a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis    return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
58671a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  }
58771a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis
58871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  const TemplateArgumentLoc &operator[](unsigned I) const {
58971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis    return getTemplateArgs()[I];
59071a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  }
59171a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis
59271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
59371a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis                                          const TemplateArgumentListInfo &List);
59471a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis
59571a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  void initializeFrom(const TemplateArgumentListInfo &List);
59671a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  void initializeFrom(const TemplateArgumentListInfo &List,
59771a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis                      bool &Dependent, bool &InstantiationDependent,
59871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis                      bool &ContainsUnexpandedParameterPack);
59971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  void copyInto(TemplateArgumentListInfo &List) const;
60071a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis  static std::size_t sizeFor(unsigned NumTemplateArgs);
601e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara};
602e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara
603e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara/// \brief Extends ASTTemplateArgumentListInfo with the source location
604e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara/// information for the template keyword; this is used as part of the
605e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara/// representation of qualified identifiers, such as S<T>::template apply<T>.
606e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnarastruct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo {
607e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  typedef ASTTemplateArgumentListInfo Base;
608e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara
609e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  // NOTE: the source location of the (optional) template keyword is
610e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  // stored after all template arguments.
611e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara
612e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  /// \brief Get the source location of the template keyword.
613e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  SourceLocation getTemplateKeywordLoc() const {
614e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    return *reinterpret_cast<const SourceLocation*>
615e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara      (getTemplateArgs() + NumTemplateArgs);
616e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  }
617e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara
618e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  /// \brief Sets the source location of the template keyword.
619e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) {
620e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    *reinterpret_cast<SourceLocation*>
621e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara      (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc;
622e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  }
623e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara
624e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  static const ASTTemplateKWAndArgsInfo*
625e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  Create(ASTContext &C, SourceLocation TemplateKWLoc,
626e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara         const TemplateArgumentListInfo &List);
627e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara
628e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  void initializeFrom(SourceLocation TemplateKWLoc,
629e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                      const TemplateArgumentListInfo &List);
630e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  void initializeFrom(SourceLocation TemplateKWLoc,
631e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                      const TemplateArgumentListInfo &List,
632e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                      bool &Dependent, bool &InstantiationDependent,
633e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                      bool &ContainsUnexpandedParameterPack);
634e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  void initializeFrom(SourceLocation TemplateKWLoc);
635e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara
636e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  static std::size_t sizeFor(unsigned NumTemplateArgs);
63771a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis};
63871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis
639a933319ebf754396623165f9dc0a29c2a48879f5Douglas Gregorconst DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
640a933319ebf754396623165f9dc0a29c2a48879f5Douglas Gregor                                    const TemplateArgument &Arg);
64133500955d731c73717af52088b7fc0e7a85681e7John McCall
64233500955d731c73717af52088b7fc0e7a85681e7John McCallinline TemplateSpecializationType::iterator
64333500955d731c73717af52088b7fc0e7a85681e7John McCall    TemplateSpecializationType::end() const {
64433500955d731c73717af52088b7fc0e7a85681e7John McCall  return getArgs() + getNumArgs();
64533500955d731c73717af52088b7fc0e7a85681e7John McCall}
64633500955d731c73717af52088b7fc0e7a85681e7John McCall
64733500955d731c73717af52088b7fc0e7a85681e7John McCallinline DependentTemplateSpecializationType::iterator
64833500955d731c73717af52088b7fc0e7a85681e7John McCall    DependentTemplateSpecializationType::end() const {
64933500955d731c73717af52088b7fc0e7a85681e7John McCall  return getArgs() + getNumArgs();
65033500955d731c73717af52088b7fc0e7a85681e7John McCall}
65133500955d731c73717af52088b7fc0e7a85681e7John McCall
65233500955d731c73717af52088b7fc0e7a85681e7John McCallinline const TemplateArgument &
65333500955d731c73717af52088b7fc0e7a85681e7John McCall    TemplateSpecializationType::getArg(unsigned Idx) const {
65433500955d731c73717af52088b7fc0e7a85681e7John McCall  assert(Idx < getNumArgs() && "Template argument out of range");
65533500955d731c73717af52088b7fc0e7a85681e7John McCall  return getArgs()[Idx];
65633500955d731c73717af52088b7fc0e7a85681e7John McCall}
65733500955d731c73717af52088b7fc0e7a85681e7John McCall
65833500955d731c73717af52088b7fc0e7a85681e7John McCallinline const TemplateArgument &
65933500955d731c73717af52088b7fc0e7a85681e7John McCall    DependentTemplateSpecializationType::getArg(unsigned Idx) const {
66033500955d731c73717af52088b7fc0e7a85681e7John McCall  assert(Idx < getNumArgs() && "Template argument out of range");
66133500955d731c73717af52088b7fc0e7a85681e7John McCall  return getArgs()[Idx];
66233500955d731c73717af52088b7fc0e7a85681e7John McCall}
663a933319ebf754396623165f9dc0a29c2a48879f5Douglas Gregor
664a933319ebf754396623165f9dc0a29c2a48879f5Douglas Gregor} // end namespace clang
665275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall
666275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall#endif
667