1327952Sdim//===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===// 2198893Srdivacky// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6198893Srdivacky// 7198893Srdivacky//===----------------------------------------------------------------------===// 8198893Srdivacky// 9198893Srdivacky// This file provides definitions which are common for all kinds of 10198893Srdivacky// template representation. 11198893Srdivacky// 12198893Srdivacky//===----------------------------------------------------------------------===// 13198893Srdivacky 14198893Srdivacky#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H 15198893Srdivacky#define LLVM_CLANG_AST_TEMPLATEBASE_H 16198893Srdivacky 17327952Sdim#include "clang/AST/NestedNameSpecifier.h" 18249423Sdim#include "clang/AST/TemplateName.h" 19234353Sdim#include "clang/AST/Type.h" 20327952Sdim#include "clang/Basic/LLVM.h" 21327952Sdim#include "clang/Basic/SourceLocation.h" 22327952Sdim#include "llvm/ADT/APInt.h" 23198893Srdivacky#include "llvm/ADT/APSInt.h" 24327952Sdim#include "llvm/ADT/ArrayRef.h" 25327952Sdim#include "llvm/ADT/None.h" 26327952Sdim#include "llvm/ADT/Optional.h" 27280031Sdim#include "llvm/ADT/SmallVector.h" 28234353Sdim#include "llvm/Support/Compiler.h" 29296417Sdim#include "llvm/Support/TrailingObjects.h" 30327952Sdim#include <cassert> 31327952Sdim#include <cstddef> 32327952Sdim#include <cstdint> 33198893Srdivacky 34198893Srdivackynamespace llvm { 35198893Srdivacky 36327952Sdimclass FoldingSetNodeID; 37327952Sdim 38327952Sdim} // namespace llvm 39327952Sdim 40198893Srdivackynamespace clang { 41198893Srdivacky 42327952Sdimclass ASTContext; 43208600Srdivackyclass DiagnosticBuilder; 44198893Srdivackyclass Expr; 45218893Sdimstruct PrintingPolicy; 46200583Srdivackyclass TypeSourceInfo; 47243830Sdimclass ValueDecl; 48198893Srdivacky 49341825Sdim/// Represents a template argument. 50198893Srdivackyclass TemplateArgument { 51198893Srdivackypublic: 52341825Sdim /// The kind of template argument we're storing. 53198893Srdivacky enum ArgKind { 54341825Sdim /// Represents an empty template argument, e.g., one that has not 55199482Srdivacky /// been deduced. 56198893Srdivacky Null = 0, 57327952Sdim 58243830Sdim /// The template argument is a type. 59199482Srdivacky Type, 60327952Sdim 61243830Sdim /// The template argument is a declaration that was provided for a pointer, 62243830Sdim /// reference, or pointer to member non-type template parameter. 63199482Srdivacky Declaration, 64327952Sdim 65243830Sdim /// The template argument is a null pointer or null pointer to member that 66243830Sdim /// was provided for a non-type template parameter. 67243830Sdim NullPtr, 68327952Sdim 69199482Srdivacky /// The template argument is an integral value stored in an llvm::APSInt 70276479Sdim /// that was provided for an integral non-type template parameter. 71199482Srdivacky Integral, 72327952Sdim 73276479Sdim /// The template argument is a template name that was provided for a 74199482Srdivacky /// template template parameter. 75199482Srdivacky Template, 76327952Sdim 77276479Sdim /// The template argument is a pack expansion of a template name that was 78218893Sdim /// provided for a template template parameter. 79218893Sdim TemplateExpansion, 80327952Sdim 81276479Sdim /// The template argument is an expression, and we've not resolved it to one 82276479Sdim /// of the other forms yet, either because it's dependent or because we're 83276479Sdim /// representing a non-canonical template argument (for instance, in a 84276479Sdim /// TemplateSpecializationType). Also used to represent a non-dependent 85276479Sdim /// __uuidof expression (a Microsoft extension). 86199482Srdivacky Expression, 87327952Sdim 88198893Srdivacky /// The template argument is actually a parameter pack. Arguments are stored 89198893Srdivacky /// in the Args struct. 90199482Srdivacky Pack 91218893Sdim }; 92198893Srdivacky 93218893Sdimprivate: 94341825Sdim /// The kind of template argument we're storing. 95218893Sdim 96249423Sdim struct DA { 97261991Sdim unsigned Kind; 98280031Sdim void *QT; 99249423Sdim ValueDecl *D; 100249423Sdim }; 101249423Sdim struct I { 102261991Sdim unsigned Kind; 103249423Sdim // We store a decomposed APSInt with the data allocated by ASTContext if 104249423Sdim // BitWidth > 64. The memory may be shared between multiple 105249423Sdim // TemplateArgument instances. 106261991Sdim unsigned BitWidth : 31; 107261991Sdim unsigned IsUnsigned : 1; 108249423Sdim union { 109327952Sdim /// Used to store the <= 64 bits integer value. 110327952Sdim uint64_t VAL; 111327952Sdim 112327952Sdim /// Used to store the >64 bits integer value. 113327952Sdim const uint64_t *pVal; 114249423Sdim }; 115249423Sdim void *Type; 116249423Sdim }; 117249423Sdim struct A { 118261991Sdim unsigned Kind; 119261991Sdim unsigned NumArgs; 120249423Sdim const TemplateArgument *Args; 121249423Sdim }; 122249423Sdim struct TA { 123261991Sdim unsigned Kind; 124261991Sdim unsigned NumExpansions; 125249423Sdim void *Name; 126249423Sdim }; 127261991Sdim struct TV { 128261991Sdim unsigned Kind; 129261991Sdim uintptr_t V; 130261991Sdim }; 131218893Sdim union { 132249423Sdim struct DA DeclArg; 133249423Sdim struct I Integer; 134249423Sdim struct A Args; 135249423Sdim struct TA TemplateArg; 136261991Sdim struct TV TypeOrValue; 137218893Sdim }; 138218893Sdim 139218893Sdimpublic: 140341825Sdim /// Construct an empty, invalid template argument. 141321369Sdim constexpr TemplateArgument() : TypeOrValue({Null, 0}) {} 142198893Srdivacky 143341825Sdim /// Construct a template type argument. 144261991Sdim TemplateArgument(QualType T, bool isNullPtr = false) { 145261991Sdim TypeOrValue.Kind = isNullPtr ? NullPtr : Type; 146261991Sdim TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); 147198893Srdivacky } 148198893Srdivacky 149341825Sdim /// Construct a template argument that refers to a 150198893Srdivacky /// declaration, which is either an external declaration or a 151198893Srdivacky /// template declaration. 152280031Sdim TemplateArgument(ValueDecl *D, QualType QT) { 153243830Sdim assert(D && "Expected decl"); 154261991Sdim DeclArg.Kind = Declaration; 155280031Sdim DeclArg.QT = QT.getAsOpaquePtr(); 156243830Sdim DeclArg.D = D; 157198893Srdivacky } 158198893Srdivacky 159341825Sdim /// Construct an integral constant template argument. The memory to 160239462Sdim /// store the value is allocated with Ctx. 161239462Sdim TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type); 162239462Sdim 163341825Sdim /// Construct an integral constant template argument with the same 164239462Sdim /// value as Other but a different type. 165261991Sdim TemplateArgument(const TemplateArgument &Other, QualType Type) { 166239462Sdim Integer = Other.Integer; 167198893Srdivacky Integer.Type = Type.getAsOpaquePtr(); 168198893Srdivacky } 169198893Srdivacky 170341825Sdim /// Construct a template argument that is a template. 171199482Srdivacky /// 172199482Srdivacky /// This form of template argument is generally used for template template 173199482Srdivacky /// parameters. However, the template name could be a dependent template 174199482Srdivacky /// name that ends up being instantiated to a function template whose address 175199482Srdivacky /// is taken. 176218893Sdim /// 177218893Sdim /// \param Name The template name. 178261991Sdim TemplateArgument(TemplateName Name) { 179261991Sdim TemplateArg.Kind = Template; 180218893Sdim TemplateArg.Name = Name.getAsVoidPointer(); 181218893Sdim TemplateArg.NumExpansions = 0; 182199482Srdivacky } 183218893Sdim 184341825Sdim /// Construct a template argument that is a template pack expansion. 185218893Sdim /// 186218893Sdim /// This form of template argument is generally used for template template 187218893Sdim /// parameters. However, the template name could be a dependent template 188218893Sdim /// name that ends up being instantiated to a function template whose address 189218893Sdim /// is taken. 190218893Sdim /// 191218893Sdim /// \param Name The template name. 192218893Sdim /// 193218893Sdim /// \param NumExpansions The number of expansions that will be generated by 194218893Sdim /// instantiating 195261991Sdim TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) { 196261991Sdim TemplateArg.Kind = TemplateExpansion; 197218893Sdim TemplateArg.Name = Name.getAsVoidPointer(); 198218893Sdim if (NumExpansions) 199218893Sdim TemplateArg.NumExpansions = *NumExpansions + 1; 200218893Sdim else 201218893Sdim TemplateArg.NumExpansions = 0; 202218893Sdim } 203218893Sdim 204341825Sdim /// Construct a template argument that is an expression. 205198893Srdivacky /// 206198893Srdivacky /// This form of template argument only occurs in template argument 207198893Srdivacky /// lists used for dependent types and for expression; it will not 208198893Srdivacky /// occur in a non-dependent, canonical template argument list. 209261991Sdim TemplateArgument(Expr *E) { 210261991Sdim TypeOrValue.Kind = Expression; 211261991Sdim TypeOrValue.V = reinterpret_cast<uintptr_t>(E); 212198893Srdivacky } 213198893Srdivacky 214341825Sdim /// Construct a template argument that is a template argument pack. 215218893Sdim /// 216218893Sdim /// We assume that storage for the template arguments provided 217218893Sdim /// outlives the TemplateArgument itself. 218296417Sdim explicit TemplateArgument(ArrayRef<TemplateArgument> Args) { 219261991Sdim this->Args.Kind = Pack; 220296417Sdim this->Args.Args = Args.data(); 221296417Sdim this->Args.NumArgs = Args.size(); 222218893Sdim } 223218893Sdim 224327952Sdim TemplateArgument(TemplateName, bool) = delete; 225327952Sdim 226296417Sdim static TemplateArgument getEmptyPack() { return TemplateArgument(None); } 227243830Sdim 228341825Sdim /// Create a new template argument pack by copying the given set of 229218893Sdim /// template arguments. 230218893Sdim static TemplateArgument CreatePackCopy(ASTContext &Context, 231296417Sdim ArrayRef<TemplateArgument> Args); 232296417Sdim 233341825Sdim /// Return the kind of stored template argument. 234261991Sdim ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; } 235198893Srdivacky 236341825Sdim /// Determine whether this template argument has no value. 237261991Sdim bool isNull() const { return getKind() == Null; } 238198893Srdivacky 239341825Sdim /// Whether this template argument is dependent on a template 240224145Sdim /// parameter such that its result can change from one instantiation to 241224145Sdim /// another. 242218893Sdim bool isDependent() const; 243218893Sdim 244341825Sdim /// Whether this template argument is dependent on a template 245224145Sdim /// parameter. 246224145Sdim bool isInstantiationDependent() const; 247224145Sdim 248341825Sdim /// Whether this template argument contains an unexpanded 249218893Sdim /// parameter pack. 250218893Sdim bool containsUnexpandedParameterPack() const; 251218893Sdim 252341825Sdim /// Determine whether this template argument is a pack expansion. 253218893Sdim bool isPackExpansion() const; 254341825Sdim 255341825Sdim /// Retrieve the type for a type template argument. 256198893Srdivacky QualType getAsType() const { 257261991Sdim assert(getKind() == Type && "Unexpected kind"); 258261991Sdim return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 259198893Srdivacky } 260198893Srdivacky 261341825Sdim /// Retrieve the declaration for a declaration non-type 262243830Sdim /// template argument. 263243830Sdim ValueDecl *getAsDecl() const { 264261991Sdim assert(getKind() == Declaration && "Unexpected kind"); 265243830Sdim return DeclArg.D; 266198893Srdivacky } 267198893Srdivacky 268280031Sdim QualType getParamTypeForDecl() const { 269261991Sdim assert(getKind() == Declaration && "Unexpected kind"); 270280031Sdim return QualType::getFromOpaquePtr(DeclArg.QT); 271243830Sdim } 272243830Sdim 273341825Sdim /// Retrieve the type for null non-type template argument. 274243830Sdim QualType getNullPtrType() const { 275261991Sdim assert(getKind() == NullPtr && "Unexpected kind"); 276261991Sdim return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 277243830Sdim } 278243830Sdim 279341825Sdim /// Retrieve the template name for a template name argument. 280199482Srdivacky TemplateName getAsTemplate() const { 281261991Sdim assert(getKind() == Template && "Unexpected kind"); 282218893Sdim return TemplateName::getFromVoidPointer(TemplateArg.Name); 283199482Srdivacky } 284218893Sdim 285341825Sdim /// Retrieve the template argument as a template name; if the argument 286218893Sdim /// is a pack expansion, return the pattern as a template name. 287218893Sdim TemplateName getAsTemplateOrTemplatePattern() const { 288261991Sdim assert((getKind() == Template || getKind() == TemplateExpansion) && 289243830Sdim "Unexpected kind"); 290341825Sdim 291218893Sdim return TemplateName::getFromVoidPointer(TemplateArg.Name); 292218893Sdim } 293218893Sdim 294341825Sdim /// Retrieve the number of expansions that a template template argument 295218893Sdim /// expansion will produce, if known. 296249423Sdim Optional<unsigned> getNumTemplateExpansions() const; 297341825Sdim 298341825Sdim /// Retrieve the template argument as an integral value. 299239462Sdim // FIXME: Provide a way to read the integral data without copying the value. 300239462Sdim llvm::APSInt getAsIntegral() const { 301261991Sdim assert(getKind() == Integral && "Unexpected kind"); 302327952Sdim 303239462Sdim using namespace llvm; 304327952Sdim 305239462Sdim if (Integer.BitWidth <= 64) 306239462Sdim return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); 307198893Srdivacky 308239462Sdim unsigned NumWords = APInt::getNumWords(Integer.BitWidth); 309239462Sdim return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)), 310239462Sdim Integer.IsUnsigned); 311198893Srdivacky } 312198893Srdivacky 313341825Sdim /// Retrieve the type of the integral value. 314198893Srdivacky QualType getIntegralType() const { 315261991Sdim assert(getKind() == Integral && "Unexpected kind"); 316198893Srdivacky return QualType::getFromOpaquePtr(Integer.Type); 317198893Srdivacky } 318198893Srdivacky 319198893Srdivacky void setIntegralType(QualType T) { 320261991Sdim assert(getKind() == Integral && "Unexpected kind"); 321198893Srdivacky Integer.Type = T.getAsOpaquePtr(); 322201361Srdivacky } 323198893Srdivacky 324341825Sdim /// If this is a non-type template argument, get its type. Otherwise, 325314564Sdim /// returns a null QualType. 326314564Sdim QualType getNonTypeTemplateArgumentType() const; 327314564Sdim 328341825Sdim /// Retrieve the template argument as an expression. 329198893Srdivacky Expr *getAsExpr() const { 330261991Sdim assert(getKind() == Expression && "Unexpected kind"); 331261991Sdim return reinterpret_cast<Expr *>(TypeOrValue.V); 332198893Srdivacky } 333198893Srdivacky 334341825Sdim /// Iterator that traverses the elements of a template argument pack. 335327952Sdim using pack_iterator = const TemplateArgument *; 336198893Srdivacky 337341825Sdim /// Iterator referencing the first argument of a template argument 338198893Srdivacky /// pack. 339198893Srdivacky pack_iterator pack_begin() const { 340261991Sdim assert(getKind() == Pack); 341198893Srdivacky return Args.Args; 342198893Srdivacky } 343198893Srdivacky 344341825Sdim /// Iterator referencing one past the last argument of a template 345198893Srdivacky /// argument pack. 346198893Srdivacky pack_iterator pack_end() const { 347261991Sdim assert(getKind() == Pack); 348198893Srdivacky return Args.Args + Args.NumArgs; 349198893Srdivacky } 350198893Srdivacky 351341825Sdim /// Iterator range referencing all of the elements of a template 352276479Sdim /// argument pack. 353314564Sdim ArrayRef<TemplateArgument> pack_elements() const { 354314564Sdim return llvm::makeArrayRef(pack_begin(), pack_end()); 355276479Sdim } 356276479Sdim 357341825Sdim /// The number of template arguments in the given template argument 358198893Srdivacky /// pack. 359198893Srdivacky unsigned pack_size() const { 360261991Sdim assert(getKind() == Pack); 361198893Srdivacky return Args.NumArgs; 362198893Srdivacky } 363198893Srdivacky 364341825Sdim /// Return the array of arguments in this template argument pack. 365276479Sdim ArrayRef<TemplateArgument> getPackAsArray() const { 366261991Sdim assert(getKind() == Pack); 367280031Sdim return llvm::makeArrayRef(Args.Args, Args.NumArgs); 368249423Sdim } 369249423Sdim 370341825Sdim /// Determines whether two template arguments are superficially the 371210299Sed /// same. 372210299Sed bool structurallyEquals(const TemplateArgument &Other) const; 373210299Sed 374341825Sdim /// When the template argument is a pack expansion, returns 375218893Sdim /// the pattern of the pack expansion. 376218893Sdim TemplateArgument getPackExpansionPattern() const; 377198893Srdivacky 378341825Sdim /// Print this template argument to the given output stream. 379226633Sdim void print(const PrintingPolicy &Policy, raw_ostream &Out) const; 380341825Sdim 381341825Sdim /// Debugging aid that dumps the template argument. 382309124Sdim void dump(raw_ostream &Out) const; 383309124Sdim 384341825Sdim /// Debugging aid that dumps the template argument to standard error. 385309124Sdim void dump() const; 386341825Sdim 387341825Sdim /// Used to insert TemplateArguments into FoldingSets. 388218893Sdim void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; 389198893Srdivacky}; 390198893Srdivacky 391198893Srdivacky/// Location information for a TemplateArgument. 392198893Srdivackystruct TemplateArgumentLocInfo { 393198893Srdivackyprivate: 394249423Sdim struct T { 395249423Sdim // FIXME: We'd like to just use the qualifier in the TemplateName, 396249423Sdim // but template arguments get canonicalized too quickly. 397249423Sdim NestedNameSpecifier *Qualifier; 398249423Sdim void *QualifierLocData; 399249423Sdim unsigned TemplateNameLoc; 400249423Sdim unsigned EllipsisLoc; 401249423Sdim }; 402249423Sdim 403198893Srdivacky union { 404249423Sdim struct T Template; 405198893Srdivacky Expr *Expression; 406200583Srdivacky TypeSourceInfo *Declarator; 407198893Srdivacky }; 408198893Srdivacky 409198893Srdivackypublic: 410321369Sdim constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {} 411321369Sdim 412218893Sdim TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {} 413341825Sdim 414218893Sdim TemplateArgumentLocInfo(Expr *E) : Expression(E) {} 415341825Sdim 416221345Sdim TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc, 417218893Sdim SourceLocation TemplateNameLoc, 418327952Sdim SourceLocation EllipsisLoc) { 419221345Sdim Template.Qualifier = QualifierLoc.getNestedNameSpecifier(); 420221345Sdim Template.QualifierLocData = QualifierLoc.getOpaqueData(); 421199482Srdivacky Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding(); 422218893Sdim Template.EllipsisLoc = EllipsisLoc.getRawEncoding(); 423199482Srdivacky } 424198893Srdivacky 425200583Srdivacky TypeSourceInfo *getAsTypeSourceInfo() const { 426198893Srdivacky return Declarator; 427198893Srdivacky } 428198893Srdivacky 429198893Srdivacky Expr *getAsExpr() const { 430198893Srdivacky return Expression; 431198893Srdivacky } 432198893Srdivacky 433221345Sdim NestedNameSpecifierLoc getTemplateQualifierLoc() const { 434341825Sdim return NestedNameSpecifierLoc(Template.Qualifier, 435221345Sdim Template.QualifierLocData); 436199482Srdivacky } 437341825Sdim 438199482Srdivacky SourceLocation getTemplateNameLoc() const { 439199482Srdivacky return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc); 440199482Srdivacky } 441341825Sdim 442218893Sdim SourceLocation getTemplateEllipsisLoc() const { 443218893Sdim return SourceLocation::getFromRawEncoding(Template.EllipsisLoc); 444198893Srdivacky } 445198893Srdivacky}; 446198893Srdivacky 447198893Srdivacky/// Location wrapper for a TemplateArgument. TemplateArgument is to 448198893Srdivacky/// TemplateArgumentLoc as Type is to TypeLoc. 449198893Srdivackyclass TemplateArgumentLoc { 450198893Srdivacky TemplateArgument Argument; 451198893Srdivacky TemplateArgumentLocInfo LocInfo; 452198893Srdivacky 453198893Srdivackypublic: 454321369Sdim constexpr TemplateArgumentLoc() {} 455198893Srdivacky 456198893Srdivacky TemplateArgumentLoc(const TemplateArgument &Argument, 457198893Srdivacky TemplateArgumentLocInfo Opaque) 458327952Sdim : Argument(Argument), LocInfo(Opaque) {} 459198893Srdivacky 460200583Srdivacky TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) 461327952Sdim : Argument(Argument), LocInfo(TInfo) { 462198893Srdivacky assert(Argument.getKind() == TemplateArgument::Type); 463198893Srdivacky } 464198893Srdivacky 465198893Srdivacky TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) 466327952Sdim : Argument(Argument), LocInfo(E) { 467341825Sdim 468341825Sdim // Permit any kind of template argument that can be represented with an 469344779Sdim // expression. 470341825Sdim assert(Argument.getKind() == TemplateArgument::NullPtr || 471341825Sdim Argument.getKind() == TemplateArgument::Integral || 472341825Sdim Argument.getKind() == TemplateArgument::Declaration || 473341825Sdim Argument.getKind() == TemplateArgument::Expression); 474198893Srdivacky } 475198893Srdivacky 476341825Sdim TemplateArgumentLoc(const TemplateArgument &Argument, 477221345Sdim NestedNameSpecifierLoc QualifierLoc, 478218893Sdim SourceLocation TemplateNameLoc, 479218893Sdim SourceLocation EllipsisLoc = SourceLocation()) 480327952Sdim : Argument(Argument), 481327952Sdim LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) { 482218893Sdim assert(Argument.getKind() == TemplateArgument::Template || 483218893Sdim Argument.getKind() == TemplateArgument::TemplateExpansion); 484199482Srdivacky } 485341825Sdim 486341825Sdim /// - Fetches the primary location of the argument. 487198893Srdivacky SourceLocation getLocation() const { 488218893Sdim if (Argument.getKind() == TemplateArgument::Template || 489218893Sdim Argument.getKind() == TemplateArgument::TemplateExpansion) 490199482Srdivacky return getTemplateNameLoc(); 491341825Sdim 492198893Srdivacky return getSourceRange().getBegin(); 493198893Srdivacky } 494198893Srdivacky 495341825Sdim /// - Fetches the full source range of the argument. 496234353Sdim SourceRange getSourceRange() const LLVM_READONLY; 497198893Srdivacky 498198893Srdivacky const TemplateArgument &getArgument() const { 499198893Srdivacky return Argument; 500198893Srdivacky } 501198893Srdivacky 502198893Srdivacky TemplateArgumentLocInfo getLocInfo() const { 503198893Srdivacky return LocInfo; 504198893Srdivacky } 505198893Srdivacky 506200583Srdivacky TypeSourceInfo *getTypeSourceInfo() const { 507198893Srdivacky assert(Argument.getKind() == TemplateArgument::Type); 508200583Srdivacky return LocInfo.getAsTypeSourceInfo(); 509198893Srdivacky } 510198893Srdivacky 511198893Srdivacky Expr *getSourceExpression() const { 512198893Srdivacky assert(Argument.getKind() == TemplateArgument::Expression); 513198893Srdivacky return LocInfo.getAsExpr(); 514198893Srdivacky } 515198893Srdivacky 516198893Srdivacky Expr *getSourceDeclExpression() const { 517198893Srdivacky assert(Argument.getKind() == TemplateArgument::Declaration); 518198893Srdivacky return LocInfo.getAsExpr(); 519198893Srdivacky } 520243830Sdim 521243830Sdim Expr *getSourceNullPtrExpression() const { 522243830Sdim assert(Argument.getKind() == TemplateArgument::NullPtr); 523243830Sdim return LocInfo.getAsExpr(); 524243830Sdim } 525243830Sdim 526243830Sdim Expr *getSourceIntegralExpression() const { 527243830Sdim assert(Argument.getKind() == TemplateArgument::Integral); 528243830Sdim return LocInfo.getAsExpr(); 529243830Sdim } 530243830Sdim 531221345Sdim NestedNameSpecifierLoc getTemplateQualifierLoc() const { 532344779Sdim if (Argument.getKind() != TemplateArgument::Template && 533344779Sdim Argument.getKind() != TemplateArgument::TemplateExpansion) 534344779Sdim return NestedNameSpecifierLoc(); 535221345Sdim return LocInfo.getTemplateQualifierLoc(); 536199482Srdivacky } 537341825Sdim 538199482Srdivacky SourceLocation getTemplateNameLoc() const { 539344779Sdim if (Argument.getKind() != TemplateArgument::Template && 540344779Sdim Argument.getKind() != TemplateArgument::TemplateExpansion) 541344779Sdim return SourceLocation(); 542199482Srdivacky return LocInfo.getTemplateNameLoc(); 543341825Sdim } 544341825Sdim 545218893Sdim SourceLocation getTemplateEllipsisLoc() const { 546344779Sdim if (Argument.getKind() != TemplateArgument::TemplateExpansion) 547344779Sdim return SourceLocation(); 548218893Sdim return LocInfo.getTemplateEllipsisLoc(); 549218893Sdim } 550198893Srdivacky}; 551198893Srdivacky 552199990Srdivacky/// A convenient class for passing around template argument 553199990Srdivacky/// information. Designed to be passed by reference. 554199990Srdivackyclass TemplateArgumentListInfo { 555226633Sdim SmallVector<TemplateArgumentLoc, 8> Arguments; 556199990Srdivacky SourceLocation LAngleLoc; 557199990Srdivacky SourceLocation RAngleLoc; 558199990Srdivacky 559199990Srdivackypublic: 560327952Sdim TemplateArgumentListInfo() = default; 561199990Srdivacky 562199990Srdivacky TemplateArgumentListInfo(SourceLocation LAngleLoc, 563199990Srdivacky SourceLocation RAngleLoc) 564327952Sdim : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} 565199990Srdivacky 566327952Sdim // This can leak if used in an AST node, use ASTTemplateArgumentListInfo 567327952Sdim // instead. 568327952Sdim void *operator new(size_t bytes, ASTContext &C) = delete; 569327952Sdim 570199990Srdivacky SourceLocation getLAngleLoc() const { return LAngleLoc; } 571199990Srdivacky SourceLocation getRAngleLoc() const { return RAngleLoc; } 572199990Srdivacky 573199990Srdivacky void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } 574199990Srdivacky void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } 575199990Srdivacky 576199990Srdivacky unsigned size() const { return Arguments.size(); } 577199990Srdivacky 578199990Srdivacky const TemplateArgumentLoc *getArgumentArray() const { 579199990Srdivacky return Arguments.data(); 580199990Srdivacky } 581199990Srdivacky 582296417Sdim llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 583296417Sdim return Arguments; 584296417Sdim } 585296417Sdim 586199990Srdivacky const TemplateArgumentLoc &operator[](unsigned I) const { 587199990Srdivacky return Arguments[I]; 588199990Srdivacky } 589199990Srdivacky 590276479Sdim TemplateArgumentLoc &operator[](unsigned I) { 591276479Sdim return Arguments[I]; 592276479Sdim } 593276479Sdim 594199990Srdivacky void addArgument(const TemplateArgumentLoc &Loc) { 595199990Srdivacky Arguments.push_back(Loc); 596199990Srdivacky } 597199990Srdivacky}; 598199990Srdivacky 599341825Sdim/// Represents an explicit template argument list in C++, e.g., 600226633Sdim/// the "<int>" in "sort<int>". 601226633Sdim/// This is safe to be used inside an AST node, in contrast with 602226633Sdim/// TemplateArgumentListInfo. 603296417Sdimstruct ASTTemplateArgumentListInfo final 604296417Sdim : private llvm::TrailingObjects<ASTTemplateArgumentListInfo, 605296417Sdim TemplateArgumentLoc> { 606296417Sdimprivate: 607327952Sdim friend class ASTNodeImporter; 608296417Sdim friend TrailingObjects; 609296417Sdim 610296417Sdim ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List); 611296417Sdim 612296417Sdimpublic: 613341825Sdim /// The source location of the left angle bracket ('<'). 614226633Sdim SourceLocation LAngleLoc; 615296417Sdim 616341825Sdim /// The source location of the right angle bracket ('>'). 617226633Sdim SourceLocation RAngleLoc; 618239462Sdim 619341825Sdim /// The number of template arguments in TemplateArgs. 620296417Sdim unsigned NumTemplateArgs; 621239462Sdim 622344779Sdim SourceLocation getLAngleLoc() const { return LAngleLoc; } 623344779Sdim SourceLocation getRAngleLoc() const { return RAngleLoc; } 624344779Sdim 625341825Sdim /// Retrieve the template arguments 626226633Sdim const TemplateArgumentLoc *getTemplateArgs() const { 627296417Sdim return getTrailingObjects<TemplateArgumentLoc>(); 628226633Sdim } 629344779Sdim unsigned getNumTemplateArgs() const { return NumTemplateArgs; } 630226633Sdim 631314564Sdim llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 632344779Sdim return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs()); 633314564Sdim } 634314564Sdim 635226633Sdim const TemplateArgumentLoc &operator[](unsigned I) const { 636226633Sdim return getTemplateArgs()[I]; 637226633Sdim } 638226633Sdim 639296417Sdim static const ASTTemplateArgumentListInfo * 640360784Sdim Create(const ASTContext &C, const TemplateArgumentListInfo &List); 641226633Sdim}; 642226633Sdim 643341825Sdim/// Represents an explicit template argument list in C++, e.g., 644296417Sdim/// the "<int>" in "sort<int>". 645296417Sdim/// 646296417Sdim/// It is intended to be used as a trailing object on AST nodes, and 647296417Sdim/// as such, doesn't contain the array of TemplateArgumentLoc itself, 648296417Sdim/// but expects the containing object to also provide storage for 649296417Sdim/// that. 650314564Sdimstruct alignas(void *) ASTTemplateKWAndArgsInfo { 651341825Sdim /// The source location of the left angle bracket ('<'). 652296417Sdim SourceLocation LAngleLoc; 653234353Sdim 654341825Sdim /// The source location of the right angle bracket ('>'). 655296417Sdim SourceLocation RAngleLoc; 656234353Sdim 657341825Sdim /// The source location of the template keyword; this is used 658296417Sdim /// as part of the representation of qualified identifiers, such as 659296417Sdim /// S<T>::template apply<T>. Will be empty if this expression does 660296417Sdim /// not have a template keyword. 661296417Sdim SourceLocation TemplateKWLoc; 662234353Sdim 663341825Sdim /// The number of template arguments in TemplateArgs. 664296417Sdim unsigned NumTemplateArgs; 665234353Sdim 666234353Sdim void initializeFrom(SourceLocation TemplateKWLoc, 667296417Sdim const TemplateArgumentListInfo &List, 668296417Sdim TemplateArgumentLoc *OutArgArray); 669234353Sdim void initializeFrom(SourceLocation TemplateKWLoc, 670234353Sdim const TemplateArgumentListInfo &List, 671296417Sdim TemplateArgumentLoc *OutArgArray, bool &Dependent, 672296417Sdim bool &InstantiationDependent, 673234353Sdim bool &ContainsUnexpandedParameterPack); 674234353Sdim void initializeFrom(SourceLocation TemplateKWLoc); 675234353Sdim 676296417Sdim void copyInto(const TemplateArgumentLoc *ArgArray, 677296417Sdim TemplateArgumentListInfo &List) const; 678234353Sdim}; 679234353Sdim 680208600Srdivackyconst DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 681208600Srdivacky const TemplateArgument &Arg); 682210299Sed 683210299Sedinline TemplateSpecializationType::iterator 684210299Sed TemplateSpecializationType::end() const { 685210299Sed return getArgs() + getNumArgs(); 686210299Sed} 687210299Sed 688210299Sedinline DependentTemplateSpecializationType::iterator 689210299Sed DependentTemplateSpecializationType::end() const { 690210299Sed return getArgs() + getNumArgs(); 691210299Sed} 692210299Sed 693210299Sedinline const TemplateArgument & 694210299Sed TemplateSpecializationType::getArg(unsigned Idx) const { 695210299Sed assert(Idx < getNumArgs() && "Template argument out of range"); 696210299Sed return getArgs()[Idx]; 697210299Sed} 698210299Sed 699210299Sedinline const TemplateArgument & 700210299Sed DependentTemplateSpecializationType::getArg(unsigned Idx) const { 701210299Sed assert(Idx < getNumArgs() && "Template argument out of range"); 702210299Sed return getArgs()[Idx]; 703210299Sed} 704341825Sdim 705360784Sdiminline const TemplateArgument &AutoType::getArg(unsigned Idx) const { 706360784Sdim assert(Idx < getNumArgs() && "Template argument out of range"); 707360784Sdim return getArgs()[Idx]; 708360784Sdim} 709360784Sdim 710327952Sdim} // namespace clang 711198893Srdivacky 712327952Sdim#endif // LLVM_CLANG_AST_TEMPLATEBASE_H 713