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 37275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall/// \brief Represents a template argument within a class template 38275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall/// specialization. 39275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCallclass TemplateArgument { 40275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCallpublic: 412bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor /// \brief The kind of template argument we're storing. 42275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall enum ArgKind { 43788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// \brief Represents an empty template argument, e.g., one that has not 44788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// been deduced. 45275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall Null = 0, 46d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// The template argument is a type. 47788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor Type, 48d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// The template argument is a declaration that was provided for a pointer, 49d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// reference, or pointer to member non-type template parameter. 50788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor Declaration, 51d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// The template argument is a null pointer or null pointer to member that 52d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// was provided for a non-type template parameter. 53d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman NullPtr, 54788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// The template argument is an integral value stored in an llvm::APSInt 55788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// that was provided for an integral non-type template parameter. 56788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor Integral, 57788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// The template argument is a template name that was provided for a 58788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// template template parameter. 59788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor Template, 60a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor /// The template argument is a pack expansion of a template name that was 61a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor /// provided for a template template parameter. 62a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor TemplateExpansion, 63275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// The template argument is a value- or type-dependent expression 64275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// stored in an Expr*. 65788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor Expression, 66275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// The template argument is actually a parameter pack. Arguments are stored 67275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// in the Args struct. 68788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor Pack 692bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor }; 702bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor 712bde8273eb5730324f823945d0c2389badf325e6Douglas Gregorprivate: 722bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor /// \brief The kind of template argument we're storing. 732bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor unsigned Kind; 74275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 75e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct DA { 76e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher ValueDecl *D; 77e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher bool ForRefParam; 78e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher }; 79e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct I { 80e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher // We store a decomposed APSInt with the data allocated by ASTContext if 81e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher // BitWidth > 64. The memory may be shared between multiple 82e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher // TemplateArgument instances. 83e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher union { 84e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher uint64_t VAL; ///< Used to store the <= 64 bits integer value. 85e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher const uint64_t *pVal; ///< Used to store the >64 bits integer value. 86e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher }; 87e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher unsigned BitWidth : 31; 88e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher unsigned IsUnsigned : 1; 89e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher void *Type; 90e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher }; 91e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct A { 92e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher const TemplateArgument *Args; 93e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher unsigned NumArgs; 94e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher }; 95e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct TA { 96e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher void *Name; 97e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher unsigned NumExpansions; 98e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher }; 992bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor union { 100e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct DA DeclArg; 101e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct I Integer; 102e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct A Args; 103e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct TA TemplateArg; 1042bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor uintptr_t TypeOrValue; 1052bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor }; 1062bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor 107e2e1fa27e2533410f744137b0db1bc9491543392David Blaikie TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION; 1082be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor 1092bde8273eb5730324f823945d0c2389badf325e6Douglas Gregorpublic: 110275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Construct an empty, invalid template argument. 111854fc56c95845660fccb1cb165fbf33fb9ae09a8Bill Wendling TemplateArgument() : Kind(Null), TypeOrValue(0) { } 112275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 113275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Construct a template type argument. 114d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman TemplateArgument(QualType T, bool isNullPtr = false) 115d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman : Kind(isNullPtr ? NullPtr : Type) { 116275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); 117275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 118275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 119275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Construct a template argument that refers to a 120275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// declaration, which is either an external declaration or a 121275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// template declaration. 122d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) { 123d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(D && "Expected decl"); 124d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman DeclArg.D = D; 125d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman DeclArg.ForRefParam = ForRefParam; 126275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 127275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 128855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer /// \brief Construct an integral constant template argument. The memory to 129855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer /// store the value is allocated with Ctx. 130855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type); 131855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer 132855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer /// \brief Construct an integral constant template argument with the same 133855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer /// value as Other but a different type. 134855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer TemplateArgument(const TemplateArgument &Other, QualType Type) 135855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer : Kind(Integral) { 136855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer Integer = Other.Integer; 137275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall Integer.Type = Type.getAsOpaquePtr(); 138275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 139275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 1402be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// \brief Construct a template argument that is a template. 141788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// 142788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// This form of template argument is generally used for template template 143788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// parameters. However, the template name could be a dependent template 144788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// name that ends up being instantiated to a function template whose address 145788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// is taken. 146ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor /// 147ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor /// \param Name The template name. 1482be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor TemplateArgument(TemplateName Name) : Kind(Template) 149ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor { 1502be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor TemplateArg.Name = Name.getAsVoidPointer(); 1512be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor TemplateArg.NumExpansions = 0; 152788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 1532be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor 1542be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// \brief Construct a template argument that is a template pack expansion. 1552be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// 1562be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// This form of template argument is generally used for template template 1572be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// parameters. However, the template name could be a dependent template 1582be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// name that ends up being instantiated to a function template whose address 1592be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// is taken. 1602be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// 1612be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// \param Name The template name. 1622be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// 1632be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// \param NumExpansions The number of expansions that will be generated by 1642be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// instantiating 165dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) 1662be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor : Kind(TemplateExpansion) 1672be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor { 1682be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor TemplateArg.Name = Name.getAsVoidPointer(); 1692be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor if (NumExpansions) 1702be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor TemplateArg.NumExpansions = *NumExpansions + 1; 1712be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor else 1722be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor TemplateArg.NumExpansions = 0; 1732be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor } 1742be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor 175275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Construct a template argument that is an expression. 176275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// 177275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// This form of template argument only occurs in template argument 178275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// lists used for dependent types and for expression; it will not 179275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// occur in a non-dependent, canonical template argument list. 180833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall TemplateArgument(Expr *E) : Kind(Expression) { 181833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall TypeOrValue = reinterpret_cast<uintptr_t>(E); 182833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 183275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 184910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor /// \brief Construct a template argument that is a template argument pack. 185910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor /// 186910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor /// We assume that storage for the template arguments provided 187910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor /// outlives the TemplateArgument itself. 188d3731198193eee92796ddeb493973b7a598b003eDouglas Gregor TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){ 189910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor this->Args.Args = Args; 190910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor this->Args.NumArgs = NumArgs; 191910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor } 192910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor 193d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman static TemplateArgument getEmptyPack() { 194d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman return TemplateArgument((TemplateArgument*)0, 0); 195d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman } 196d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman 197203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor /// \brief Create a new template argument pack by copying the given set of 198203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor /// template arguments. 199203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor static TemplateArgument CreatePackCopy(ASTContext &Context, 200203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor const TemplateArgument *Args, 201203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor unsigned NumArgs); 202203e6a322ae29d577acafcb1572a57ec16e1e730Douglas Gregor 203275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Return the kind of stored template argument. 2042bde8273eb5730324f823945d0c2389badf325e6Douglas Gregor ArgKind getKind() const { return (ArgKind)Kind; } 205275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 206275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Determine whether this template argument has no value. 207275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall bool isNull() const { return Kind == Null; } 208275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 209bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor /// \brief Whether this template argument is dependent on a template 210561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor /// parameter such that its result can change from one instantiation to 211561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor /// another. 212bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor bool isDependent() const; 213bebbe0d9b7568ce43a464286bee49429489ef483Douglas Gregor 214561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor /// \brief Whether this template argument is dependent on a template 215561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor /// parameter. 216561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor bool isInstantiationDependent() const; 217561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor 218d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor /// \brief Whether this template argument contains an unexpanded 219d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor /// parameter pack. 220d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor bool containsUnexpandedParameterPack() const; 221d0937224f383c7cc72c947119380f9713a070c73Douglas Gregor 2228491ffe86c50241b47c6d7ef8cd9ee00f5e675daDouglas Gregor /// \brief Determine whether this template argument is a pack expansion. 2238491ffe86c50241b47c6d7ef8cd9ee00f5e675daDouglas Gregor bool isPackExpansion() const; 2248491ffe86c50241b47c6d7ef8cd9ee00f5e675daDouglas Gregor 225d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// \brief Retrieve the type for a type template argument. 226275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall QualType getAsType() const { 227d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Kind == Type && "Unexpected kind"); 228275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); 229275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 230275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 231d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// \brief Retrieve the declaration for a declaration non-type 232d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// template argument. 233d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman ValueDecl *getAsDecl() const { 234d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Kind == Declaration && "Unexpected kind"); 235d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman return DeclArg.D; 236d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman } 237d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman 238d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// \brief Retrieve whether a declaration is binding to a 239d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// reference parameter in a declaration non-type template argument. 240d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman bool isDeclForReferenceParam() const { 241d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Kind == Declaration && "Unexpected kind"); 242d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman return DeclArg.ForRefParam; 243275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 244275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 245d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// \brief Retrieve the type for null non-type template argument. 246d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman QualType getNullPtrType() const { 247d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Kind == NullPtr && "Unexpected kind"); 248d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); 249d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman } 250d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman 251d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman /// \brief Retrieve the template name for a template name argument. 252788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor TemplateName getAsTemplate() const { 253d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Kind == Template && "Unexpected kind"); 2542be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor return TemplateName::getFromVoidPointer(TemplateArg.Name); 255788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 256a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor 257a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor /// \brief Retrieve the template argument as a template name; if the argument 258a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor /// is a pack expansion, return the pattern as a template name. 259a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor TemplateName getAsTemplateOrTemplatePattern() const { 260d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert((Kind == Template || Kind == TemplateExpansion) && 261d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman "Unexpected kind"); 262a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor 2632be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor return TemplateName::getFromVoidPointer(TemplateArg.Name); 264a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor } 265a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor 2662be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// \brief Retrieve the number of expansions that a template template argument 2672be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor /// expansion will produce, if known. 268dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<unsigned> getNumTemplateExpansions() const; 2692be29f423acad3bbe39099a78db2805acb5bdf17Douglas Gregor 270275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Retrieve the template argument as an integral value. 271855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer // FIXME: Provide a way to read the integral data without copying the value. 272855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer llvm::APSInt getAsIntegral() const { 273d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Kind == Integral && "Unexpected kind"); 274b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer using namespace llvm; 275855243789cb44799c03f4c7216d3d6308805f549Benjamin Kramer if (Integer.BitWidth <= 64) 276b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); 277b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer 278b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer unsigned NumWords = APInt::getNumWords(Integer.BitWidth); 279b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)), 280b8e54cd26cc71075456a74be054a95fa1f2e28adBenjamin Kramer Integer.IsUnsigned); 281275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 282275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 283275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Retrieve the type of the integral value. 284275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall QualType getIntegralType() const { 285d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Kind == Integral && "Unexpected kind"); 286275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall return QualType::getFromOpaquePtr(Integer.Type); 287275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 288275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 289275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall void setIntegralType(QualType T) { 290d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Kind == Integral && "Unexpected kind"); 291275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall Integer.Type = T.getAsOpaquePtr(); 2927177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar } 293275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 294275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Retrieve the template argument as an expression. 295275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall Expr *getAsExpr() const { 296d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Kind == Expression && "Unexpected kind"); 297275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall return reinterpret_cast<Expr *>(TypeOrValue); 298275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 299275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 300275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Iterator that traverses the elements of a template argument pack. 301275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall typedef const TemplateArgument * pack_iterator; 302275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 303275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Iterator referencing the first argument of a template argument 304275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// pack. 305275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall pack_iterator pack_begin() const { 306275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall assert(Kind == Pack); 307275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall return Args.Args; 308275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 309275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 310275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Iterator referencing one past the last argument of a template 311275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// argument pack. 312275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall pack_iterator pack_end() const { 313275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall assert(Kind == Pack); 314275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall return Args.Args + Args.NumArgs; 315275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 316275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 317275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief The number of template arguments in the given template argument 318275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// pack. 319275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall unsigned pack_size() const { 320275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall assert(Kind == Pack); 321275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall return Args.NumArgs; 322275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall } 323275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 3245a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall /// \brief Return the array of arguments in this template argument pack. 3255a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall llvm::ArrayRef<TemplateArgument> getPackAsArray() const { 3265a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall assert(Kind == Pack); 3275a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs); 3285a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall } 3295a758de93fa2a28a84eb0d918a31d9522472990cJohn McCall 330efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett /// \brief Determines whether two template arguments are superficially the 33133500955d731c73717af52088b7fc0e7a85681e7John McCall /// same. 33233500955d731c73717af52088b7fc0e7a85681e7John McCall bool structurallyEquals(const TemplateArgument &Other) const; 33333500955d731c73717af52088b7fc0e7a85681e7John McCall 334efce31f51d6e7e31e125f96c20f6cdab3ead0a47James Dennett /// \brief When the template argument is a pack expansion, returns 335e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor /// the pattern of the pack expansion. 336e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor TemplateArgument getPackExpansionPattern() const; 337e02e26293cf8e3bad1059b39cea75c6582896da6Douglas Gregor 33887dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor /// \brief Print this template argument to the given output stream. 3398cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner void print(const PrintingPolicy &Policy, raw_ostream &Out) const; 34087dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor 341275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall /// \brief Used to insert TemplateArguments into FoldingSets. 3424ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; 343275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall}; 344275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 345833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall/// Location information for a TemplateArgument. 346833ca991c1bfc967f0995974ca86f66ba1f666b5John McCallstruct TemplateArgumentLocInfo { 347833ca991c1bfc967f0995974ca86f66ba1f666b5John McCallprivate: 348e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher 349e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct T { 350e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher // FIXME: We'd like to just use the qualifier in the TemplateName, 351e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher // but template arguments get canonicalized too quickly. 352e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher NestedNameSpecifier *Qualifier; 353e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher void *QualifierLocData; 354e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher unsigned TemplateNameLoc; 355e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher unsigned EllipsisLoc; 356e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher }; 357e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher 358828bff2079b6a91ecd7ed5b842c59527d7682789John McCall union { 359e462c60ac3365d3302b7d0a566c5cb7dbe0e5ae3Eric Christopher struct T Template; 360828bff2079b6a91ecd7ed5b842c59527d7682789John McCall Expr *Expression; 361a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TypeSourceInfo *Declarator; 362828bff2079b6a91ecd7ed5b842c59527d7682789John McCall }; 363833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 364833ca991c1bfc967f0995974ca86f66ba1f666b5John McCallpublic: 365b0ddf3aeb2f119cac42468b029584e8839b354ccDouglas Gregor TemplateArgumentLocInfo(); 3668de39b431d3775cd46584080beec3a75d019bd28Douglas Gregor 3676939fff69a3dfff2552261a1d7f1f609380fe6b0Douglas Gregor TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {} 3688de39b431d3775cd46584080beec3a75d019bd28Douglas Gregor 3696939fff69a3dfff2552261a1d7f1f609380fe6b0Douglas Gregor TemplateArgumentLocInfo(Expr *E) : Expression(E) {} 370788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor 371b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc, 372ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor SourceLocation TemplateNameLoc, 373ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor SourceLocation EllipsisLoc) 374788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor { 375b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor Template.Qualifier = QualifierLoc.getNestedNameSpecifier(); 376b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor Template.QualifierLocData = QualifierLoc.getOpaqueData(); 377788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding(); 378ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor Template.EllipsisLoc = EllipsisLoc.getRawEncoding(); 379788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 380833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 381a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TypeSourceInfo *getAsTypeSourceInfo() const { 382828bff2079b6a91ecd7ed5b842c59527d7682789John McCall return Declarator; 383833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 384833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 385833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall Expr *getAsExpr() const { 386828bff2079b6a91ecd7ed5b842c59527d7682789John McCall return Expression; 387833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 388833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 389b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor NestedNameSpecifierLoc getTemplateQualifierLoc() const { 390b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor return NestedNameSpecifierLoc(Template.Qualifier, 391b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor Template.QualifierLocData); 392788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 393788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor 394788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor SourceLocation getTemplateNameLoc() const { 395788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc); 396788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 397ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor 398ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor SourceLocation getTemplateEllipsisLoc() const { 399ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor return SourceLocation::getFromRawEncoding(Template.EllipsisLoc); 400ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor } 401833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall}; 402833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 403833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall/// Location wrapper for a TemplateArgument. TemplateArgument is to 404833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall/// TemplateArgumentLoc as Type is to TypeLoc. 405833ca991c1bfc967f0995974ca86f66ba1f666b5John McCallclass TemplateArgumentLoc { 406833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall TemplateArgument Argument; 407833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall TemplateArgumentLocInfo LocInfo; 408833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 409828bff2079b6a91ecd7ed5b842c59527d7682789John McCallpublic: 410828bff2079b6a91ecd7ed5b842c59527d7682789John McCall TemplateArgumentLoc() {} 411828bff2079b6a91ecd7ed5b842c59527d7682789John McCall 412833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall TemplateArgumentLoc(const TemplateArgument &Argument, 413833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall TemplateArgumentLocInfo Opaque) 414833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall : Argument(Argument), LocInfo(Opaque) { 415833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 416833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 417a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) 418a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall : Argument(Argument), LocInfo(TInfo) { 419833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall assert(Argument.getKind() == TemplateArgument::Type); 420833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 421833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 422833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) 423833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall : Argument(Argument), LocInfo(E) { 424833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall assert(Argument.getKind() == TemplateArgument::Expression); 425833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 426833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 427788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor TemplateArgumentLoc(const TemplateArgument &Argument, 428b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor NestedNameSpecifierLoc QualifierLoc, 429ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor SourceLocation TemplateNameLoc, 430ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor SourceLocation EllipsisLoc = SourceLocation()) 431b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) { 432a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor assert(Argument.getKind() == TemplateArgument::Template || 433a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor Argument.getKind() == TemplateArgument::TemplateExpansion); 434788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 435788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor 436788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor /// \brief - Fetches the primary location of the argument. 437828bff2079b6a91ecd7ed5b842c59527d7682789John McCall SourceLocation getLocation() const { 438a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor if (Argument.getKind() == TemplateArgument::Template || 439a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor Argument.getKind() == TemplateArgument::TemplateExpansion) 440788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor return getTemplateNameLoc(); 441788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor 442828bff2079b6a91ecd7ed5b842c59527d7682789John McCall return getSourceRange().getBegin(); 443833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 444833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 445828bff2079b6a91ecd7ed5b842c59527d7682789John McCall /// \brief - Fetches the full source range of the argument. 446aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar SourceRange getSourceRange() const LLVM_READONLY; 447833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 448833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall const TemplateArgument &getArgument() const { 449833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall return Argument; 450833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 451833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 452833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall TemplateArgumentLocInfo getLocInfo() const { 453833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall return LocInfo; 454833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 455833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 456a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall TypeSourceInfo *getTypeSourceInfo() const { 457833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall assert(Argument.getKind() == TemplateArgument::Type); 458a93c934af4fbf97cbe8e649d82e68ccacfe57c95John McCall return LocInfo.getAsTypeSourceInfo(); 459833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 460833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 461833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall Expr *getSourceExpression() const { 462833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall assert(Argument.getKind() == TemplateArgument::Expression); 463828bff2079b6a91ecd7ed5b842c59527d7682789John McCall return LocInfo.getAsExpr(); 464828bff2079b6a91ecd7ed5b842c59527d7682789John McCall } 465828bff2079b6a91ecd7ed5b842c59527d7682789John McCall 466828bff2079b6a91ecd7ed5b842c59527d7682789John McCall Expr *getSourceDeclExpression() const { 467828bff2079b6a91ecd7ed5b842c59527d7682789John McCall assert(Argument.getKind() == TemplateArgument::Declaration); 468833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall return LocInfo.getAsExpr(); 469833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall } 470d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman 471d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman Expr *getSourceNullPtrExpression() const { 472d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Argument.getKind() == TemplateArgument::NullPtr); 473d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman return LocInfo.getAsExpr(); 474d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman } 475d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman 476d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman Expr *getSourceIntegralExpression() const { 477d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman assert(Argument.getKind() == TemplateArgument::Integral); 478d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman return LocInfo.getAsExpr(); 479d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman } 480d7a6b1640e565487d163023a6a2e83f55476ae96Eli Friedman 481b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor NestedNameSpecifierLoc getTemplateQualifierLoc() const { 482a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor assert(Argument.getKind() == TemplateArgument::Template || 483a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor Argument.getKind() == TemplateArgument::TemplateExpansion); 484b6744efecba58792cce20d2d7b9ee39927c5422eDouglas Gregor return LocInfo.getTemplateQualifierLoc(); 485788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 486788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor 487788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor SourceLocation getTemplateNameLoc() const { 488a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor assert(Argument.getKind() == TemplateArgument::Template || 489a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor Argument.getKind() == TemplateArgument::TemplateExpansion); 490788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor return LocInfo.getTemplateNameLoc(); 491788cd06cf8e868a67158aafec5de3a1f408d14f3Douglas Gregor } 4928491ffe86c50241b47c6d7ef8cd9ee00f5e675daDouglas Gregor 493ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor SourceLocation getTemplateEllipsisLoc() const { 494a7fc901a2e39bfe55bfcff5934b2d9fdf9656491Douglas Gregor assert(Argument.getKind() == TemplateArgument::TemplateExpansion); 495ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor return LocInfo.getTemplateEllipsisLoc(); 496ba68eca7582a62e3e2ff4b0eba1b2b73a6b80895Douglas Gregor } 497833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall}; 498833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall 499d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall/// A convenient class for passing around template argument 500d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall/// information. Designed to be passed by reference. 501d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallclass TemplateArgumentListInfo { 502686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<TemplateArgumentLoc, 8> Arguments; 503d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall SourceLocation LAngleLoc; 504d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall SourceLocation RAngleLoc; 505d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 50671a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis // This can leak if used in an AST node, use ASTTemplateArgumentListInfo 50771a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis // instead. 50871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis void* operator new(size_t bytes, ASTContext& C); 50971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis 510d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallpublic: 511d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall TemplateArgumentListInfo() {} 512d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 513d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall TemplateArgumentListInfo(SourceLocation LAngleLoc, 514d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall SourceLocation RAngleLoc) 515d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} 516d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 517d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall SourceLocation getLAngleLoc() const { return LAngleLoc; } 518d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall SourceLocation getRAngleLoc() const { return RAngleLoc; } 519d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 520d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } 521d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } 522d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 523d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall unsigned size() const { return Arguments.size(); } 524d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 525d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall const TemplateArgumentLoc *getArgumentArray() const { 526d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall return Arguments.data(); 527d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall } 528d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 529d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall const TemplateArgumentLoc &operator[](unsigned I) const { 530d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall return Arguments[I]; 531d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall } 532d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 533d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall void addArgument(const TemplateArgumentLoc &Loc) { 534d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall Arguments.push_back(Loc); 535d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall } 536d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall}; 537d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall 53871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis/// \brief Represents an explicit template argument list in C++, e.g., 53971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis/// the "<int>" in "sort<int>". 54071a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis/// This is safe to be used inside an AST node, in contrast with 54171a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis/// TemplateArgumentListInfo. 54271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidisstruct ASTTemplateArgumentListInfo { 54397f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith /// \brief The source location of the left angle bracket ('<'). 54471a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis SourceLocation LAngleLoc; 54571a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis 54697f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith /// \brief The source location of the right angle bracket ('>'). 54771a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis SourceLocation RAngleLoc; 54871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis 54997f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith union { 55097f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith /// \brief The number of template arguments in TemplateArgs. 55197f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith /// The actual template arguments (if any) are stored after the 55297f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith /// ExplicitTemplateArgumentList structure. 55397f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith unsigned NumTemplateArgs; 55497f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith 55597f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith /// Force ASTTemplateArgumentListInfo to the right alignment 55697f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith /// for the following array of TemplateArgumentLocs. 55797f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith void *Aligner; 55897f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith }; 55997f6026f460c3aaa250fc9dcd7c2b8b6c1f3ba69Richard Smith 56071a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis /// \brief Retrieve the template arguments 56171a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis TemplateArgumentLoc *getTemplateArgs() { 56271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis return reinterpret_cast<TemplateArgumentLoc *> (this + 1); 56371a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis } 56471a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis 56571a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis /// \brief Retrieve the template arguments 56671a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis const TemplateArgumentLoc *getTemplateArgs() const { 56771a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis return reinterpret_cast<const TemplateArgumentLoc *> (this + 1); 56871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis } 56971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis 57071a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis const TemplateArgumentLoc &operator[](unsigned I) const { 57171a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis return getTemplateArgs()[I]; 57271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis } 57371a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis 57471a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis static const ASTTemplateArgumentListInfo *Create(ASTContext &C, 57571a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis const TemplateArgumentListInfo &List); 57671a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis 57771a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis void initializeFrom(const TemplateArgumentListInfo &List); 57871a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis void initializeFrom(const TemplateArgumentListInfo &List, 57971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis bool &Dependent, bool &InstantiationDependent, 58071a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis bool &ContainsUnexpandedParameterPack); 58171a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis void copyInto(TemplateArgumentListInfo &List) const; 58271a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis static std::size_t sizeFor(unsigned NumTemplateArgs); 583e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara}; 584e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara 585e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara/// \brief Extends ASTTemplateArgumentListInfo with the source location 586e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara/// information for the template keyword; this is used as part of the 587e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara/// representation of qualified identifiers, such as S<T>::template apply<T>. 588e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnarastruct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo { 589e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara typedef ASTTemplateArgumentListInfo Base; 590e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara 591e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara // NOTE: the source location of the (optional) template keyword is 592e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara // stored after all template arguments. 593e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara 594e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara /// \brief Get the source location of the template keyword. 595e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation getTemplateKeywordLoc() const { 596e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara return *reinterpret_cast<const SourceLocation*> 597e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara (getTemplateArgs() + NumTemplateArgs); 598e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara } 599e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara 600e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara /// \brief Sets the source location of the template keyword. 601e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) { 602e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara *reinterpret_cast<SourceLocation*> 603e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc; 604e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara } 605e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara 606e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara static const ASTTemplateKWAndArgsInfo* 607e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara Create(ASTContext &C, SourceLocation TemplateKWLoc, 608e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara const TemplateArgumentListInfo &List); 609e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara 610e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara void initializeFrom(SourceLocation TemplateKWLoc, 611e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara const TemplateArgumentListInfo &List); 612e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara void initializeFrom(SourceLocation TemplateKWLoc, 613e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara const TemplateArgumentListInfo &List, 614e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara bool &Dependent, bool &InstantiationDependent, 615e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara bool &ContainsUnexpandedParameterPack); 616e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara void initializeFrom(SourceLocation TemplateKWLoc); 617e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara 618e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara static std::size_t sizeFor(unsigned NumTemplateArgs); 61971a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis}; 62071a7605977113c795edd44fcbd2302ad49506653Argyrios Kyrtzidis 621a933319ebf754396623165f9dc0a29c2a48879f5Douglas Gregorconst DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 622a933319ebf754396623165f9dc0a29c2a48879f5Douglas Gregor const TemplateArgument &Arg); 62333500955d731c73717af52088b7fc0e7a85681e7John McCall 62433500955d731c73717af52088b7fc0e7a85681e7John McCallinline TemplateSpecializationType::iterator 62533500955d731c73717af52088b7fc0e7a85681e7John McCall TemplateSpecializationType::end() const { 62633500955d731c73717af52088b7fc0e7a85681e7John McCall return getArgs() + getNumArgs(); 62733500955d731c73717af52088b7fc0e7a85681e7John McCall} 62833500955d731c73717af52088b7fc0e7a85681e7John McCall 62933500955d731c73717af52088b7fc0e7a85681e7John McCallinline DependentTemplateSpecializationType::iterator 63033500955d731c73717af52088b7fc0e7a85681e7John McCall DependentTemplateSpecializationType::end() const { 63133500955d731c73717af52088b7fc0e7a85681e7John McCall return getArgs() + getNumArgs(); 63233500955d731c73717af52088b7fc0e7a85681e7John McCall} 63333500955d731c73717af52088b7fc0e7a85681e7John McCall 63433500955d731c73717af52088b7fc0e7a85681e7John McCallinline const TemplateArgument & 63533500955d731c73717af52088b7fc0e7a85681e7John McCall TemplateSpecializationType::getArg(unsigned Idx) const { 63633500955d731c73717af52088b7fc0e7a85681e7John McCall assert(Idx < getNumArgs() && "Template argument out of range"); 63733500955d731c73717af52088b7fc0e7a85681e7John McCall return getArgs()[Idx]; 63833500955d731c73717af52088b7fc0e7a85681e7John McCall} 63933500955d731c73717af52088b7fc0e7a85681e7John McCall 64033500955d731c73717af52088b7fc0e7a85681e7John McCallinline const TemplateArgument & 64133500955d731c73717af52088b7fc0e7a85681e7John McCall DependentTemplateSpecializationType::getArg(unsigned Idx) const { 64233500955d731c73717af52088b7fc0e7a85681e7John McCall assert(Idx < getNumArgs() && "Template argument out of range"); 64333500955d731c73717af52088b7fc0e7a85681e7John McCall return getArgs()[Idx]; 64433500955d731c73717af52088b7fc0e7a85681e7John McCall} 645a933319ebf754396623165f9dc0a29c2a48879f5Douglas Gregor 646a933319ebf754396623165f9dc0a29c2a48879f5Douglas Gregor} // end namespace clang 647275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall 648275c10a8a4a43219f67d8d2c912ec6294d9d9af2John McCall#endif 649