1198893Srdivacky//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===// 2198893Srdivacky// 3198893Srdivacky// The LLVM Compiler Infrastructure 4198893Srdivacky// 5198893Srdivacky// This file is distributed under the University of Illinois Open Source 6198893Srdivacky// License. See LICENSE.TXT for details. 7198893Srdivacky// 8198893Srdivacky//===----------------------------------------------------------------------===// 9198893Srdivacky// 10198893Srdivacky// This file provides definitions which are common for all kinds of 11198893Srdivacky// template representation. 12198893Srdivacky// 13198893Srdivacky//===----------------------------------------------------------------------===// 14198893Srdivacky 15198893Srdivacky#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H 16198893Srdivacky#define LLVM_CLANG_AST_TEMPLATEBASE_H 17198893Srdivacky 18252723Sdim#include "clang/AST/TemplateName.h" 19235633Sdim#include "clang/AST/Type.h" 20198893Srdivacky#include "llvm/ADT/APSInt.h" 21199990Srdivacky#include "llvm/ADT/SmallVector.h" 22235633Sdim#include "llvm/Support/Compiler.h" 23198893Srdivacky#include "llvm/Support/ErrorHandling.h" 24198893Srdivacky 25198893Srdivackynamespace llvm { 26198893Srdivacky class FoldingSetNodeID; 27198893Srdivacky} 28198893Srdivacky 29198893Srdivackynamespace clang { 30198893Srdivacky 31208600Srdivackyclass DiagnosticBuilder; 32198893Srdivackyclass Expr; 33218893Sdimstruct PrintingPolicy; 34200583Srdivackyclass TypeSourceInfo; 35245431Sdimclass ValueDecl; 36198893Srdivacky 37198893Srdivacky/// \brief Represents a template argument within a class template 38198893Srdivacky/// specialization. 39198893Srdivackyclass TemplateArgument { 40198893Srdivackypublic: 41218893Sdim /// \brief The kind of template argument we're storing. 42198893Srdivacky enum ArgKind { 43199482Srdivacky /// \brief Represents an empty template argument, e.g., one that has not 44199482Srdivacky /// been deduced. 45198893Srdivacky Null = 0, 46245431Sdim /// The template argument is a type. 47199482Srdivacky Type, 48245431Sdim /// The template argument is a declaration that was provided for a pointer, 49245431Sdim /// reference, or pointer to member non-type template parameter. 50199482Srdivacky Declaration, 51245431Sdim /// The template argument is a null pointer or null pointer to member that 52245431Sdim /// was provided for a non-type template parameter. 53245431Sdim NullPtr, 54199482Srdivacky /// The template argument is an integral value stored in an llvm::APSInt 55199482Srdivacky /// that was provided for an integral non-type template parameter. 56199482Srdivacky Integral, 57199482Srdivacky /// The template argument is a template name that was provided for a 58199482Srdivacky /// template template parameter. 59199482Srdivacky Template, 60218893Sdim /// The template argument is a pack expansion of a template name that was 61218893Sdim /// provided for a template template parameter. 62218893Sdim TemplateExpansion, 63263509Sdim /// The template argument is a value- or type-dependent expression or a 64263509Sdim /// non-dependent __uuidof expression stored in an Expr*. 65199482Srdivacky Expression, 66198893Srdivacky /// The template argument is actually a parameter pack. Arguments are stored 67198893Srdivacky /// in the Args struct. 68199482Srdivacky Pack 69218893Sdim }; 70198893Srdivacky 71218893Sdimprivate: 72218893Sdim /// \brief The kind of template argument we're storing. 73218893Sdim 74252723Sdim struct DA { 75263509Sdim unsigned Kind; 76263509Sdim bool ForRefParam; 77252723Sdim ValueDecl *D; 78252723Sdim }; 79252723Sdim struct I { 80263509Sdim unsigned Kind; 81252723Sdim // We store a decomposed APSInt with the data allocated by ASTContext if 82252723Sdim // BitWidth > 64. The memory may be shared between multiple 83252723Sdim // TemplateArgument instances. 84263509Sdim unsigned BitWidth : 31; 85263509Sdim unsigned IsUnsigned : 1; 86252723Sdim union { 87252723Sdim uint64_t VAL; ///< Used to store the <= 64 bits integer value. 88252723Sdim const uint64_t *pVal; ///< Used to store the >64 bits integer value. 89252723Sdim }; 90252723Sdim void *Type; 91252723Sdim }; 92252723Sdim struct A { 93263509Sdim unsigned Kind; 94263509Sdim unsigned NumArgs; 95252723Sdim const TemplateArgument *Args; 96252723Sdim }; 97252723Sdim struct TA { 98263509Sdim unsigned Kind; 99263509Sdim unsigned NumExpansions; 100252723Sdim void *Name; 101252723Sdim }; 102263509Sdim struct TV { 103263509Sdim unsigned Kind; 104263509Sdim uintptr_t V; 105263509Sdim }; 106218893Sdim union { 107252723Sdim struct DA DeclArg; 108252723Sdim struct I Integer; 109252723Sdim struct A Args; 110252723Sdim struct TA TemplateArg; 111263509Sdim struct TV TypeOrValue; 112218893Sdim }; 113218893Sdim 114252723Sdim TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION; 115218893Sdim 116218893Sdimpublic: 117198893Srdivacky /// \brief Construct an empty, invalid template argument. 118263509Sdim TemplateArgument() { 119263509Sdim TypeOrValue.Kind = Null; 120263509Sdim TypeOrValue.V = 0; 121263509Sdim } 122198893Srdivacky 123198893Srdivacky /// \brief Construct a template type argument. 124263509Sdim TemplateArgument(QualType T, bool isNullPtr = false) { 125263509Sdim TypeOrValue.Kind = isNullPtr ? NullPtr : Type; 126263509Sdim TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); 127198893Srdivacky } 128198893Srdivacky 129198893Srdivacky /// \brief Construct a template argument that refers to a 130198893Srdivacky /// declaration, which is either an external declaration or a 131198893Srdivacky /// template declaration. 132263509Sdim TemplateArgument(ValueDecl *D, bool ForRefParam) { 133245431Sdim assert(D && "Expected decl"); 134263509Sdim DeclArg.Kind = Declaration; 135245431Sdim DeclArg.D = D; 136245431Sdim DeclArg.ForRefParam = ForRefParam; 137198893Srdivacky } 138198893Srdivacky 139245431Sdim /// \brief Construct an integral constant template argument. The memory to 140245431Sdim /// store the value is allocated with Ctx. 141245431Sdim TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type); 142245431Sdim 143245431Sdim /// \brief Construct an integral constant template argument with the same 144245431Sdim /// value as Other but a different type. 145263509Sdim TemplateArgument(const TemplateArgument &Other, QualType Type) { 146245431Sdim Integer = Other.Integer; 147198893Srdivacky Integer.Type = Type.getAsOpaquePtr(); 148198893Srdivacky } 149198893Srdivacky 150199482Srdivacky /// \brief Construct a template argument that is a template. 151199482Srdivacky /// 152199482Srdivacky /// This form of template argument is generally used for template template 153199482Srdivacky /// parameters. However, the template name could be a dependent template 154199482Srdivacky /// name that ends up being instantiated to a function template whose address 155199482Srdivacky /// is taken. 156218893Sdim /// 157218893Sdim /// \param Name The template name. 158263509Sdim TemplateArgument(TemplateName Name) { 159263509Sdim TemplateArg.Kind = Template; 160218893Sdim TemplateArg.Name = Name.getAsVoidPointer(); 161218893Sdim TemplateArg.NumExpansions = 0; 162199482Srdivacky } 163218893Sdim 164218893Sdim /// \brief Construct a template argument that is a template pack expansion. 165218893Sdim /// 166218893Sdim /// This form of template argument is generally used for template template 167218893Sdim /// parameters. However, the template name could be a dependent template 168218893Sdim /// name that ends up being instantiated to a function template whose address 169218893Sdim /// is taken. 170218893Sdim /// 171218893Sdim /// \param Name The template name. 172218893Sdim /// 173218893Sdim /// \param NumExpansions The number of expansions that will be generated by 174218893Sdim /// instantiating 175263509Sdim TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) { 176263509Sdim TemplateArg.Kind = TemplateExpansion; 177218893Sdim TemplateArg.Name = Name.getAsVoidPointer(); 178218893Sdim if (NumExpansions) 179218893Sdim TemplateArg.NumExpansions = *NumExpansions + 1; 180218893Sdim else 181218893Sdim TemplateArg.NumExpansions = 0; 182218893Sdim } 183218893Sdim 184198893Srdivacky /// \brief Construct a template argument that is an expression. 185198893Srdivacky /// 186198893Srdivacky /// This form of template argument only occurs in template argument 187198893Srdivacky /// lists used for dependent types and for expression; it will not 188198893Srdivacky /// occur in a non-dependent, canonical template argument list. 189263509Sdim TemplateArgument(Expr *E) { 190263509Sdim TypeOrValue.Kind = Expression; 191263509Sdim TypeOrValue.V = reinterpret_cast<uintptr_t>(E); 192198893Srdivacky } 193198893Srdivacky 194218893Sdim /// \brief Construct a template argument that is a template argument pack. 195218893Sdim /// 196218893Sdim /// We assume that storage for the template arguments provided 197218893Sdim /// outlives the TemplateArgument itself. 198263509Sdim TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) { 199263509Sdim this->Args.Kind = Pack; 200218893Sdim this->Args.Args = Args; 201218893Sdim this->Args.NumArgs = NumArgs; 202218893Sdim } 203218893Sdim 204245431Sdim static TemplateArgument getEmptyPack() { 205245431Sdim return TemplateArgument((TemplateArgument*)0, 0); 206198893Srdivacky } 207198893Srdivacky 208218893Sdim /// \brief Create a new template argument pack by copying the given set of 209218893Sdim /// template arguments. 210218893Sdim static TemplateArgument CreatePackCopy(ASTContext &Context, 211218893Sdim const TemplateArgument *Args, 212218893Sdim unsigned NumArgs); 213218893Sdim 214198893Srdivacky /// \brief Return the kind of stored template argument. 215263509Sdim ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; } 216198893Srdivacky 217198893Srdivacky /// \brief Determine whether this template argument has no value. 218263509Sdim bool isNull() const { return getKind() == Null; } 219198893Srdivacky 220218893Sdim /// \brief Whether this template argument is dependent on a template 221224145Sdim /// parameter such that its result can change from one instantiation to 222224145Sdim /// another. 223218893Sdim bool isDependent() const; 224218893Sdim 225224145Sdim /// \brief Whether this template argument is dependent on a template 226224145Sdim /// parameter. 227224145Sdim bool isInstantiationDependent() const; 228224145Sdim 229218893Sdim /// \brief Whether this template argument contains an unexpanded 230218893Sdim /// parameter pack. 231218893Sdim bool containsUnexpandedParameterPack() const; 232218893Sdim 233218893Sdim /// \brief Determine whether this template argument is a pack expansion. 234218893Sdim bool isPackExpansion() const; 235218893Sdim 236245431Sdim /// \brief Retrieve the type for a type template argument. 237198893Srdivacky QualType getAsType() const { 238263509Sdim assert(getKind() == Type && "Unexpected kind"); 239263509Sdim return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 240198893Srdivacky } 241198893Srdivacky 242245431Sdim /// \brief Retrieve the declaration for a declaration non-type 243245431Sdim /// template argument. 244245431Sdim ValueDecl *getAsDecl() const { 245263509Sdim assert(getKind() == Declaration && "Unexpected kind"); 246245431Sdim return DeclArg.D; 247198893Srdivacky } 248198893Srdivacky 249245431Sdim /// \brief Retrieve whether a declaration is binding to a 250245431Sdim /// reference parameter in a declaration non-type template argument. 251245431Sdim bool isDeclForReferenceParam() const { 252263509Sdim assert(getKind() == Declaration && "Unexpected kind"); 253245431Sdim return DeclArg.ForRefParam; 254245431Sdim } 255245431Sdim 256245431Sdim /// \brief Retrieve the type for null non-type template argument. 257245431Sdim QualType getNullPtrType() const { 258263509Sdim assert(getKind() == NullPtr && "Unexpected kind"); 259263509Sdim return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 260245431Sdim } 261245431Sdim 262245431Sdim /// \brief Retrieve the template name for a template name argument. 263199482Srdivacky TemplateName getAsTemplate() const { 264263509Sdim assert(getKind() == Template && "Unexpected kind"); 265218893Sdim return TemplateName::getFromVoidPointer(TemplateArg.Name); 266199482Srdivacky } 267218893Sdim 268218893Sdim /// \brief Retrieve the template argument as a template name; if the argument 269218893Sdim /// is a pack expansion, return the pattern as a template name. 270218893Sdim TemplateName getAsTemplateOrTemplatePattern() const { 271263509Sdim assert((getKind() == Template || getKind() == TemplateExpansion) && 272245431Sdim "Unexpected kind"); 273218893Sdim 274218893Sdim return TemplateName::getFromVoidPointer(TemplateArg.Name); 275218893Sdim } 276218893Sdim 277218893Sdim /// \brief Retrieve the number of expansions that a template template argument 278218893Sdim /// expansion will produce, if known. 279252723Sdim Optional<unsigned> getNumTemplateExpansions() const; 280199482Srdivacky 281198893Srdivacky /// \brief Retrieve the template argument as an integral value. 282245431Sdim // FIXME: Provide a way to read the integral data without copying the value. 283245431Sdim llvm::APSInt getAsIntegral() const { 284263509Sdim assert(getKind() == Integral && "Unexpected kind"); 285245431Sdim using namespace llvm; 286245431Sdim if (Integer.BitWidth <= 64) 287245431Sdim return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); 288198893Srdivacky 289245431Sdim unsigned NumWords = APInt::getNumWords(Integer.BitWidth); 290245431Sdim return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)), 291245431Sdim Integer.IsUnsigned); 292198893Srdivacky } 293198893Srdivacky 294198893Srdivacky /// \brief Retrieve the type of the integral value. 295198893Srdivacky QualType getIntegralType() const { 296263509Sdim assert(getKind() == Integral && "Unexpected kind"); 297198893Srdivacky return QualType::getFromOpaquePtr(Integer.Type); 298198893Srdivacky } 299198893Srdivacky 300198893Srdivacky void setIntegralType(QualType T) { 301263509Sdim assert(getKind() == Integral && "Unexpected kind"); 302198893Srdivacky Integer.Type = T.getAsOpaquePtr(); 303201361Srdivacky } 304198893Srdivacky 305198893Srdivacky /// \brief Retrieve the template argument as an expression. 306198893Srdivacky Expr *getAsExpr() const { 307263509Sdim assert(getKind() == Expression && "Unexpected kind"); 308263509Sdim return reinterpret_cast<Expr *>(TypeOrValue.V); 309198893Srdivacky } 310198893Srdivacky 311198893Srdivacky /// \brief Iterator that traverses the elements of a template argument pack. 312198893Srdivacky typedef const TemplateArgument * pack_iterator; 313198893Srdivacky 314198893Srdivacky /// \brief Iterator referencing the first argument of a template argument 315198893Srdivacky /// pack. 316198893Srdivacky pack_iterator pack_begin() const { 317263509Sdim assert(getKind() == Pack); 318198893Srdivacky return Args.Args; 319198893Srdivacky } 320198893Srdivacky 321198893Srdivacky /// \brief Iterator referencing one past the last argument of a template 322198893Srdivacky /// argument pack. 323198893Srdivacky pack_iterator pack_end() const { 324263509Sdim assert(getKind() == Pack); 325198893Srdivacky return Args.Args + Args.NumArgs; 326198893Srdivacky } 327198893Srdivacky 328198893Srdivacky /// \brief The number of template arguments in the given template argument 329198893Srdivacky /// pack. 330198893Srdivacky unsigned pack_size() const { 331263509Sdim assert(getKind() == Pack); 332198893Srdivacky return Args.NumArgs; 333198893Srdivacky } 334198893Srdivacky 335252723Sdim /// \brief Return the array of arguments in this template argument pack. 336252723Sdim llvm::ArrayRef<TemplateArgument> getPackAsArray() const { 337263509Sdim assert(getKind() == Pack); 338252723Sdim return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs); 339252723Sdim } 340252723Sdim 341245431Sdim /// \brief Determines whether two template arguments are superficially the 342210299Sed /// same. 343210299Sed bool structurallyEquals(const TemplateArgument &Other) const; 344210299Sed 345245431Sdim /// \brief When the template argument is a pack expansion, returns 346218893Sdim /// the pattern of the pack expansion. 347218893Sdim TemplateArgument getPackExpansionPattern() const; 348198893Srdivacky 349218893Sdim /// \brief Print this template argument to the given output stream. 350226890Sdim void print(const PrintingPolicy &Policy, raw_ostream &Out) const; 351218893Sdim 352198893Srdivacky /// \brief Used to insert TemplateArguments into FoldingSets. 353218893Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; 354198893Srdivacky}; 355198893Srdivacky 356198893Srdivacky/// Location information for a TemplateArgument. 357198893Srdivackystruct TemplateArgumentLocInfo { 358198893Srdivackyprivate: 359252723Sdim 360252723Sdim struct T { 361252723Sdim // FIXME: We'd like to just use the qualifier in the TemplateName, 362252723Sdim // but template arguments get canonicalized too quickly. 363252723Sdim NestedNameSpecifier *Qualifier; 364252723Sdim void *QualifierLocData; 365252723Sdim unsigned TemplateNameLoc; 366252723Sdim unsigned EllipsisLoc; 367252723Sdim }; 368252723Sdim 369198893Srdivacky union { 370252723Sdim struct T Template; 371198893Srdivacky Expr *Expression; 372200583Srdivacky TypeSourceInfo *Declarator; 373198893Srdivacky }; 374198893Srdivacky 375198893Srdivackypublic: 376218893Sdim TemplateArgumentLocInfo(); 377198893Srdivacky 378218893Sdim TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {} 379198893Srdivacky 380218893Sdim TemplateArgumentLocInfo(Expr *E) : Expression(E) {} 381199482Srdivacky 382221345Sdim TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc, 383218893Sdim SourceLocation TemplateNameLoc, 384218893Sdim SourceLocation EllipsisLoc) 385199482Srdivacky { 386221345Sdim Template.Qualifier = QualifierLoc.getNestedNameSpecifier(); 387221345Sdim Template.QualifierLocData = QualifierLoc.getOpaqueData(); 388199482Srdivacky Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding(); 389218893Sdim Template.EllipsisLoc = EllipsisLoc.getRawEncoding(); 390199482Srdivacky } 391198893Srdivacky 392200583Srdivacky TypeSourceInfo *getAsTypeSourceInfo() const { 393198893Srdivacky return Declarator; 394198893Srdivacky } 395198893Srdivacky 396198893Srdivacky Expr *getAsExpr() const { 397198893Srdivacky return Expression; 398198893Srdivacky } 399198893Srdivacky 400221345Sdim NestedNameSpecifierLoc getTemplateQualifierLoc() const { 401221345Sdim return NestedNameSpecifierLoc(Template.Qualifier, 402221345Sdim Template.QualifierLocData); 403199482Srdivacky } 404199482Srdivacky 405199482Srdivacky SourceLocation getTemplateNameLoc() const { 406199482Srdivacky return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc); 407199482Srdivacky } 408199482Srdivacky 409218893Sdim SourceLocation getTemplateEllipsisLoc() const { 410218893Sdim return SourceLocation::getFromRawEncoding(Template.EllipsisLoc); 411198893Srdivacky } 412198893Srdivacky}; 413198893Srdivacky 414198893Srdivacky/// Location wrapper for a TemplateArgument. TemplateArgument is to 415198893Srdivacky/// TemplateArgumentLoc as Type is to TypeLoc. 416198893Srdivackyclass TemplateArgumentLoc { 417198893Srdivacky TemplateArgument Argument; 418198893Srdivacky TemplateArgumentLocInfo LocInfo; 419198893Srdivacky 420198893Srdivackypublic: 421198893Srdivacky TemplateArgumentLoc() {} 422198893Srdivacky 423198893Srdivacky TemplateArgumentLoc(const TemplateArgument &Argument, 424198893Srdivacky TemplateArgumentLocInfo Opaque) 425198893Srdivacky : Argument(Argument), LocInfo(Opaque) { 426198893Srdivacky } 427198893Srdivacky 428200583Srdivacky TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) 429200583Srdivacky : Argument(Argument), LocInfo(TInfo) { 430198893Srdivacky assert(Argument.getKind() == TemplateArgument::Type); 431198893Srdivacky } 432198893Srdivacky 433198893Srdivacky TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) 434198893Srdivacky : Argument(Argument), LocInfo(E) { 435198893Srdivacky assert(Argument.getKind() == TemplateArgument::Expression); 436198893Srdivacky } 437198893Srdivacky 438199482Srdivacky TemplateArgumentLoc(const TemplateArgument &Argument, 439221345Sdim NestedNameSpecifierLoc QualifierLoc, 440218893Sdim SourceLocation TemplateNameLoc, 441218893Sdim SourceLocation EllipsisLoc = SourceLocation()) 442221345Sdim : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) { 443218893Sdim assert(Argument.getKind() == TemplateArgument::Template || 444218893Sdim Argument.getKind() == TemplateArgument::TemplateExpansion); 445199482Srdivacky } 446199482Srdivacky 447199482Srdivacky /// \brief - Fetches the primary location of the argument. 448198893Srdivacky SourceLocation getLocation() const { 449218893Sdim if (Argument.getKind() == TemplateArgument::Template || 450218893Sdim Argument.getKind() == TemplateArgument::TemplateExpansion) 451199482Srdivacky return getTemplateNameLoc(); 452199482Srdivacky 453198893Srdivacky return getSourceRange().getBegin(); 454198893Srdivacky } 455198893Srdivacky 456198893Srdivacky /// \brief - Fetches the full source range of the argument. 457235633Sdim SourceRange getSourceRange() const LLVM_READONLY; 458198893Srdivacky 459198893Srdivacky const TemplateArgument &getArgument() const { 460198893Srdivacky return Argument; 461198893Srdivacky } 462198893Srdivacky 463198893Srdivacky TemplateArgumentLocInfo getLocInfo() const { 464198893Srdivacky return LocInfo; 465198893Srdivacky } 466198893Srdivacky 467200583Srdivacky TypeSourceInfo *getTypeSourceInfo() const { 468198893Srdivacky assert(Argument.getKind() == TemplateArgument::Type); 469200583Srdivacky return LocInfo.getAsTypeSourceInfo(); 470198893Srdivacky } 471198893Srdivacky 472198893Srdivacky Expr *getSourceExpression() const { 473198893Srdivacky assert(Argument.getKind() == TemplateArgument::Expression); 474198893Srdivacky return LocInfo.getAsExpr(); 475198893Srdivacky } 476198893Srdivacky 477198893Srdivacky Expr *getSourceDeclExpression() const { 478198893Srdivacky assert(Argument.getKind() == TemplateArgument::Declaration); 479198893Srdivacky return LocInfo.getAsExpr(); 480198893Srdivacky } 481245431Sdim 482245431Sdim Expr *getSourceNullPtrExpression() const { 483245431Sdim assert(Argument.getKind() == TemplateArgument::NullPtr); 484245431Sdim return LocInfo.getAsExpr(); 485245431Sdim } 486245431Sdim 487245431Sdim Expr *getSourceIntegralExpression() const { 488245431Sdim assert(Argument.getKind() == TemplateArgument::Integral); 489245431Sdim return LocInfo.getAsExpr(); 490245431Sdim } 491245431Sdim 492221345Sdim NestedNameSpecifierLoc getTemplateQualifierLoc() const { 493218893Sdim assert(Argument.getKind() == TemplateArgument::Template || 494218893Sdim Argument.getKind() == TemplateArgument::TemplateExpansion); 495221345Sdim return LocInfo.getTemplateQualifierLoc(); 496199482Srdivacky } 497199482Srdivacky 498199482Srdivacky SourceLocation getTemplateNameLoc() const { 499218893Sdim assert(Argument.getKind() == TemplateArgument::Template || 500218893Sdim Argument.getKind() == TemplateArgument::TemplateExpansion); 501199482Srdivacky return LocInfo.getTemplateNameLoc(); 502199482Srdivacky } 503218893Sdim 504218893Sdim SourceLocation getTemplateEllipsisLoc() const { 505218893Sdim assert(Argument.getKind() == TemplateArgument::TemplateExpansion); 506218893Sdim return LocInfo.getTemplateEllipsisLoc(); 507218893Sdim } 508198893Srdivacky}; 509198893Srdivacky 510199990Srdivacky/// A convenient class for passing around template argument 511199990Srdivacky/// information. Designed to be passed by reference. 512199990Srdivackyclass TemplateArgumentListInfo { 513226890Sdim SmallVector<TemplateArgumentLoc, 8> Arguments; 514199990Srdivacky SourceLocation LAngleLoc; 515199990Srdivacky SourceLocation RAngleLoc; 516199990Srdivacky 517226890Sdim // This can leak if used in an AST node, use ASTTemplateArgumentListInfo 518226890Sdim // instead. 519226890Sdim void* operator new(size_t bytes, ASTContext& C); 520226890Sdim 521199990Srdivackypublic: 522199990Srdivacky TemplateArgumentListInfo() {} 523199990Srdivacky 524199990Srdivacky TemplateArgumentListInfo(SourceLocation LAngleLoc, 525199990Srdivacky SourceLocation RAngleLoc) 526199990Srdivacky : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} 527199990Srdivacky 528199990Srdivacky SourceLocation getLAngleLoc() const { return LAngleLoc; } 529199990Srdivacky SourceLocation getRAngleLoc() const { return RAngleLoc; } 530199990Srdivacky 531199990Srdivacky void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } 532199990Srdivacky void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } 533199990Srdivacky 534199990Srdivacky unsigned size() const { return Arguments.size(); } 535199990Srdivacky 536199990Srdivacky const TemplateArgumentLoc *getArgumentArray() const { 537199990Srdivacky return Arguments.data(); 538199990Srdivacky } 539199990Srdivacky 540199990Srdivacky const TemplateArgumentLoc &operator[](unsigned I) const { 541199990Srdivacky return Arguments[I]; 542199990Srdivacky } 543199990Srdivacky 544199990Srdivacky void addArgument(const TemplateArgumentLoc &Loc) { 545199990Srdivacky Arguments.push_back(Loc); 546199990Srdivacky } 547199990Srdivacky}; 548199990Srdivacky 549226890Sdim/// \brief Represents an explicit template argument list in C++, e.g., 550226890Sdim/// the "<int>" in "sort<int>". 551226890Sdim/// This is safe to be used inside an AST node, in contrast with 552226890Sdim/// TemplateArgumentListInfo. 553226890Sdimstruct ASTTemplateArgumentListInfo { 554245431Sdim /// \brief The source location of the left angle bracket ('<'). 555226890Sdim SourceLocation LAngleLoc; 556226890Sdim 557245431Sdim /// \brief The source location of the right angle bracket ('>'). 558226890Sdim SourceLocation RAngleLoc; 559226890Sdim 560245431Sdim union { 561245431Sdim /// \brief The number of template arguments in TemplateArgs. 562245431Sdim /// The actual template arguments (if any) are stored after the 563245431Sdim /// ExplicitTemplateArgumentList structure. 564245431Sdim unsigned NumTemplateArgs; 565245431Sdim 566245431Sdim /// Force ASTTemplateArgumentListInfo to the right alignment 567245431Sdim /// for the following array of TemplateArgumentLocs. 568245431Sdim void *Aligner; 569245431Sdim }; 570245431Sdim 571226890Sdim /// \brief Retrieve the template arguments 572226890Sdim TemplateArgumentLoc *getTemplateArgs() { 573226890Sdim return reinterpret_cast<TemplateArgumentLoc *> (this + 1); 574226890Sdim } 575226890Sdim 576226890Sdim /// \brief Retrieve the template arguments 577226890Sdim const TemplateArgumentLoc *getTemplateArgs() const { 578226890Sdim return reinterpret_cast<const TemplateArgumentLoc *> (this + 1); 579226890Sdim } 580226890Sdim 581226890Sdim const TemplateArgumentLoc &operator[](unsigned I) const { 582226890Sdim return getTemplateArgs()[I]; 583226890Sdim } 584226890Sdim 585226890Sdim static const ASTTemplateArgumentListInfo *Create(ASTContext &C, 586226890Sdim const TemplateArgumentListInfo &List); 587226890Sdim 588226890Sdim void initializeFrom(const TemplateArgumentListInfo &List); 589226890Sdim void initializeFrom(const TemplateArgumentListInfo &List, 590226890Sdim bool &Dependent, bool &InstantiationDependent, 591226890Sdim bool &ContainsUnexpandedParameterPack); 592226890Sdim void copyInto(TemplateArgumentListInfo &List) const; 593226890Sdim static std::size_t sizeFor(unsigned NumTemplateArgs); 594226890Sdim}; 595226890Sdim 596235633Sdim/// \brief Extends ASTTemplateArgumentListInfo with the source location 597235633Sdim/// information for the template keyword; this is used as part of the 598235633Sdim/// representation of qualified identifiers, such as S<T>::template apply<T>. 599235633Sdimstruct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo { 600235633Sdim typedef ASTTemplateArgumentListInfo Base; 601235633Sdim 602235633Sdim // NOTE: the source location of the (optional) template keyword is 603235633Sdim // stored after all template arguments. 604235633Sdim 605235633Sdim /// \brief Get the source location of the template keyword. 606235633Sdim SourceLocation getTemplateKeywordLoc() const { 607235633Sdim return *reinterpret_cast<const SourceLocation*> 608235633Sdim (getTemplateArgs() + NumTemplateArgs); 609235633Sdim } 610235633Sdim 611235633Sdim /// \brief Sets the source location of the template keyword. 612235633Sdim void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) { 613235633Sdim *reinterpret_cast<SourceLocation*> 614235633Sdim (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc; 615235633Sdim } 616235633Sdim 617235633Sdim static const ASTTemplateKWAndArgsInfo* 618235633Sdim Create(ASTContext &C, SourceLocation TemplateKWLoc, 619235633Sdim const TemplateArgumentListInfo &List); 620235633Sdim 621235633Sdim void initializeFrom(SourceLocation TemplateKWLoc, 622235633Sdim const TemplateArgumentListInfo &List); 623235633Sdim void initializeFrom(SourceLocation TemplateKWLoc, 624235633Sdim const TemplateArgumentListInfo &List, 625235633Sdim bool &Dependent, bool &InstantiationDependent, 626235633Sdim bool &ContainsUnexpandedParameterPack); 627235633Sdim void initializeFrom(SourceLocation TemplateKWLoc); 628235633Sdim 629235633Sdim static std::size_t sizeFor(unsigned NumTemplateArgs); 630235633Sdim}; 631235633Sdim 632208600Srdivackyconst DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 633208600Srdivacky const TemplateArgument &Arg); 634210299Sed 635210299Sedinline TemplateSpecializationType::iterator 636210299Sed TemplateSpecializationType::end() const { 637210299Sed return getArgs() + getNumArgs(); 638210299Sed} 639210299Sed 640210299Sedinline DependentTemplateSpecializationType::iterator 641210299Sed DependentTemplateSpecializationType::end() const { 642210299Sed return getArgs() + getNumArgs(); 643210299Sed} 644210299Sed 645210299Sedinline const TemplateArgument & 646210299Sed TemplateSpecializationType::getArg(unsigned Idx) const { 647210299Sed assert(Idx < getNumArgs() && "Template argument out of range"); 648210299Sed return getArgs()[Idx]; 649210299Sed} 650210299Sed 651210299Sedinline const TemplateArgument & 652210299Sed DependentTemplateSpecializationType::getArg(unsigned Idx) const { 653210299Sed assert(Idx < getNumArgs() && "Template argument out of range"); 654210299Sed return getArgs()[Idx]; 655210299Sed} 656208600Srdivacky 657208600Srdivacky} // end namespace clang 658198893Srdivacky 659198893Srdivacky#endif 660