TemplateBase.h revision e2e1fa27e2533410f744137b0db1bc9491543392
1//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file provides definitions which are common for all kinds of 11// template representation. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H 16#define LLVM_CLANG_AST_TEMPLATEBASE_H 17 18#include "clang/AST/TemplateName.h" 19#include "clang/AST/Type.h" 20#include "llvm/ADT/APSInt.h" 21#include "llvm/ADT/SmallVector.h" 22#include "llvm/Support/Compiler.h" 23#include "llvm/Support/ErrorHandling.h" 24 25namespace llvm { 26 class FoldingSetNodeID; 27} 28 29namespace clang { 30 31class DiagnosticBuilder; 32class Expr; 33struct PrintingPolicy; 34class TypeSourceInfo; 35class ValueDecl; 36 37/// \brief Represents a template argument within a class template 38/// specialization. 39class TemplateArgument { 40public: 41 /// \brief The kind of template argument we're storing. 42 enum ArgKind { 43 /// \brief Represents an empty template argument, e.g., one that has not 44 /// been deduced. 45 Null = 0, 46 /// The template argument is a type. 47 Type, 48 /// The template argument is a declaration that was provided for a pointer, 49 /// reference, or pointer to member non-type template parameter. 50 Declaration, 51 /// The template argument is a null pointer or null pointer to member that 52 /// was provided for a non-type template parameter. 53 NullPtr, 54 /// The template argument is an integral value stored in an llvm::APSInt 55 /// that was provided for an integral non-type template parameter. 56 Integral, 57 /// The template argument is a template name that was provided for a 58 /// template template parameter. 59 Template, 60 /// The template argument is a pack expansion of a template name that was 61 /// provided for a template template parameter. 62 TemplateExpansion, 63 /// The template argument is a value- or type-dependent expression 64 /// stored in an Expr*. 65 Expression, 66 /// The template argument is actually a parameter pack. Arguments are stored 67 /// in the Args struct. 68 Pack 69 }; 70 71private: 72 /// \brief The kind of template argument we're storing. 73 unsigned Kind; 74 75 union { 76 uintptr_t TypeOrValue; 77 struct { 78 ValueDecl *D; 79 bool ForRefParam; 80 } DeclArg; 81 struct { 82 // We store a decomposed APSInt with the data allocated by ASTContext if 83 // BitWidth > 64. The memory may be shared between multiple 84 // TemplateArgument instances. 85 union { 86 uint64_t VAL; ///< Used to store the <= 64 bits integer value. 87 const uint64_t *pVal; ///< Used to store the >64 bits integer value. 88 }; 89 unsigned BitWidth : 31; 90 unsigned IsUnsigned : 1; 91 void *Type; 92 } Integer; 93 struct { 94 const TemplateArgument *Args; 95 unsigned NumArgs; 96 } Args; 97 struct { 98 void *Name; 99 unsigned NumExpansions; 100 } TemplateArg; 101 }; 102 103 TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION; 104 105public: 106 /// \brief Construct an empty, invalid template argument. 107 TemplateArgument() : Kind(Null), TypeOrValue(0) { } 108 109 /// \brief Construct a template type argument. 110 TemplateArgument(QualType T, bool isNullPtr = false) 111 : Kind(isNullPtr ? NullPtr : Type) { 112 TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); 113 } 114 115 /// \brief Construct a template argument that refers to a 116 /// declaration, which is either an external declaration or a 117 /// template declaration. 118 TemplateArgument(ValueDecl *D, bool ForRefParam) : Kind(Declaration) { 119 assert(D && "Expected decl"); 120 DeclArg.D = D; 121 DeclArg.ForRefParam = ForRefParam; 122 } 123 124 /// \brief Construct an integral constant template argument. The memory to 125 /// store the value is allocated with Ctx. 126 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type); 127 128 /// \brief Construct an integral constant template argument with the same 129 /// value as Other but a different type. 130 TemplateArgument(const TemplateArgument &Other, QualType Type) 131 : Kind(Integral) { 132 Integer = Other.Integer; 133 Integer.Type = Type.getAsOpaquePtr(); 134 } 135 136 /// \brief Construct a template argument that is a template. 137 /// 138 /// This form of template argument is generally used for template template 139 /// parameters. However, the template name could be a dependent template 140 /// name that ends up being instantiated to a function template whose address 141 /// is taken. 142 /// 143 /// \param Name The template name. 144 TemplateArgument(TemplateName Name) : Kind(Template) 145 { 146 TemplateArg.Name = Name.getAsVoidPointer(); 147 TemplateArg.NumExpansions = 0; 148 } 149 150 /// \brief Construct a template argument that is a template pack expansion. 151 /// 152 /// This form of template argument is generally used for template template 153 /// parameters. However, the template name could be a dependent template 154 /// name that ends up being instantiated to a function template whose address 155 /// is taken. 156 /// 157 /// \param Name The template name. 158 /// 159 /// \param NumExpansions The number of expansions that will be generated by 160 /// instantiating 161 TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) 162 : Kind(TemplateExpansion) 163 { 164 TemplateArg.Name = Name.getAsVoidPointer(); 165 if (NumExpansions) 166 TemplateArg.NumExpansions = *NumExpansions + 1; 167 else 168 TemplateArg.NumExpansions = 0; 169 } 170 171 /// \brief Construct a template argument that is an expression. 172 /// 173 /// This form of template argument only occurs in template argument 174 /// lists used for dependent types and for expression; it will not 175 /// occur in a non-dependent, canonical template argument list. 176 TemplateArgument(Expr *E) : Kind(Expression) { 177 TypeOrValue = reinterpret_cast<uintptr_t>(E); 178 } 179 180 /// \brief Construct a template argument that is a template argument pack. 181 /// 182 /// We assume that storage for the template arguments provided 183 /// outlives the TemplateArgument itself. 184 TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){ 185 this->Args.Args = Args; 186 this->Args.NumArgs = NumArgs; 187 } 188 189 static TemplateArgument getEmptyPack() { 190 return TemplateArgument((TemplateArgument*)0, 0); 191 } 192 193 /// \brief Create a new template argument pack by copying the given set of 194 /// template arguments. 195 static TemplateArgument CreatePackCopy(ASTContext &Context, 196 const TemplateArgument *Args, 197 unsigned NumArgs); 198 199 /// \brief Return the kind of stored template argument. 200 ArgKind getKind() const { return (ArgKind)Kind; } 201 202 /// \brief Determine whether this template argument has no value. 203 bool isNull() const { return Kind == Null; } 204 205 /// \brief Whether this template argument is dependent on a template 206 /// parameter such that its result can change from one instantiation to 207 /// another. 208 bool isDependent() const; 209 210 /// \brief Whether this template argument is dependent on a template 211 /// parameter. 212 bool isInstantiationDependent() const; 213 214 /// \brief Whether this template argument contains an unexpanded 215 /// parameter pack. 216 bool containsUnexpandedParameterPack() const; 217 218 /// \brief Determine whether this template argument is a pack expansion. 219 bool isPackExpansion() const; 220 221 /// \brief Retrieve the type for a type template argument. 222 QualType getAsType() const { 223 assert(Kind == Type && "Unexpected kind"); 224 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); 225 } 226 227 /// \brief Retrieve the declaration for a declaration non-type 228 /// template argument. 229 ValueDecl *getAsDecl() const { 230 assert(Kind == Declaration && "Unexpected kind"); 231 return DeclArg.D; 232 } 233 234 /// \brief Retrieve whether a declaration is binding to a 235 /// reference parameter in a declaration non-type template argument. 236 bool isDeclForReferenceParam() const { 237 assert(Kind == Declaration && "Unexpected kind"); 238 return DeclArg.ForRefParam; 239 } 240 241 /// \brief Retrieve the type for null non-type template argument. 242 QualType getNullPtrType() const { 243 assert(Kind == NullPtr && "Unexpected kind"); 244 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); 245 } 246 247 /// \brief Retrieve the template name for a template name argument. 248 TemplateName getAsTemplate() const { 249 assert(Kind == Template && "Unexpected kind"); 250 return TemplateName::getFromVoidPointer(TemplateArg.Name); 251 } 252 253 /// \brief Retrieve the template argument as a template name; if the argument 254 /// is a pack expansion, return the pattern as a template name. 255 TemplateName getAsTemplateOrTemplatePattern() const { 256 assert((Kind == Template || Kind == TemplateExpansion) && 257 "Unexpected kind"); 258 259 return TemplateName::getFromVoidPointer(TemplateArg.Name); 260 } 261 262 /// \brief Retrieve the number of expansions that a template template argument 263 /// expansion will produce, if known. 264 Optional<unsigned> getNumTemplateExpansions() const; 265 266 /// \brief Retrieve the template argument as an integral value. 267 // FIXME: Provide a way to read the integral data without copying the value. 268 llvm::APSInt getAsIntegral() const { 269 assert(Kind == Integral && "Unexpected kind"); 270 using namespace llvm; 271 if (Integer.BitWidth <= 64) 272 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); 273 274 unsigned NumWords = APInt::getNumWords(Integer.BitWidth); 275 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)), 276 Integer.IsUnsigned); 277 } 278 279 /// \brief Retrieve the type of the integral value. 280 QualType getIntegralType() const { 281 assert(Kind == Integral && "Unexpected kind"); 282 return QualType::getFromOpaquePtr(Integer.Type); 283 } 284 285 void setIntegralType(QualType T) { 286 assert(Kind == Integral && "Unexpected kind"); 287 Integer.Type = T.getAsOpaquePtr(); 288 } 289 290 /// \brief Retrieve the template argument as an expression. 291 Expr *getAsExpr() const { 292 assert(Kind == Expression && "Unexpected kind"); 293 return reinterpret_cast<Expr *>(TypeOrValue); 294 } 295 296 /// \brief Iterator that traverses the elements of a template argument pack. 297 typedef const TemplateArgument * pack_iterator; 298 299 /// \brief Iterator referencing the first argument of a template argument 300 /// pack. 301 pack_iterator pack_begin() const { 302 assert(Kind == Pack); 303 return Args.Args; 304 } 305 306 /// \brief Iterator referencing one past the last argument of a template 307 /// argument pack. 308 pack_iterator pack_end() const { 309 assert(Kind == Pack); 310 return Args.Args + Args.NumArgs; 311 } 312 313 /// \brief The number of template arguments in the given template argument 314 /// pack. 315 unsigned pack_size() const { 316 assert(Kind == Pack); 317 return Args.NumArgs; 318 } 319 320 /// \brief Return the array of arguments in this template argument pack. 321 llvm::ArrayRef<TemplateArgument> getPackAsArray() const { 322 assert(Kind == Pack); 323 return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs); 324 } 325 326 /// \brief Determines whether two template arguments are superficially the 327 /// same. 328 bool structurallyEquals(const TemplateArgument &Other) const; 329 330 /// \brief When the template argument is a pack expansion, returns 331 /// the pattern of the pack expansion. 332 TemplateArgument getPackExpansionPattern() const; 333 334 /// \brief Print this template argument to the given output stream. 335 void print(const PrintingPolicy &Policy, raw_ostream &Out) const; 336 337 /// \brief Used to insert TemplateArguments into FoldingSets. 338 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; 339}; 340 341/// Location information for a TemplateArgument. 342struct TemplateArgumentLocInfo { 343private: 344 union { 345 Expr *Expression; 346 TypeSourceInfo *Declarator; 347 struct { 348 // FIXME: We'd like to just use the qualifier in the TemplateName, 349 // but template arguments get canonicalized too quickly. 350 NestedNameSpecifier *Qualifier; 351 void *QualifierLocData; 352 unsigned TemplateNameLoc; 353 unsigned EllipsisLoc; 354 } Template; 355 }; 356 357public: 358 TemplateArgumentLocInfo(); 359 360 TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {} 361 362 TemplateArgumentLocInfo(Expr *E) : Expression(E) {} 363 364 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc, 365 SourceLocation TemplateNameLoc, 366 SourceLocation EllipsisLoc) 367 { 368 Template.Qualifier = QualifierLoc.getNestedNameSpecifier(); 369 Template.QualifierLocData = QualifierLoc.getOpaqueData(); 370 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding(); 371 Template.EllipsisLoc = EllipsisLoc.getRawEncoding(); 372 } 373 374 TypeSourceInfo *getAsTypeSourceInfo() const { 375 return Declarator; 376 } 377 378 Expr *getAsExpr() const { 379 return Expression; 380 } 381 382 NestedNameSpecifierLoc getTemplateQualifierLoc() const { 383 return NestedNameSpecifierLoc(Template.Qualifier, 384 Template.QualifierLocData); 385 } 386 387 SourceLocation getTemplateNameLoc() const { 388 return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc); 389 } 390 391 SourceLocation getTemplateEllipsisLoc() const { 392 return SourceLocation::getFromRawEncoding(Template.EllipsisLoc); 393 } 394}; 395 396/// Location wrapper for a TemplateArgument. TemplateArgument is to 397/// TemplateArgumentLoc as Type is to TypeLoc. 398class TemplateArgumentLoc { 399 TemplateArgument Argument; 400 TemplateArgumentLocInfo LocInfo; 401 402public: 403 TemplateArgumentLoc() {} 404 405 TemplateArgumentLoc(const TemplateArgument &Argument, 406 TemplateArgumentLocInfo Opaque) 407 : Argument(Argument), LocInfo(Opaque) { 408 } 409 410 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) 411 : Argument(Argument), LocInfo(TInfo) { 412 assert(Argument.getKind() == TemplateArgument::Type); 413 } 414 415 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) 416 : Argument(Argument), LocInfo(E) { 417 assert(Argument.getKind() == TemplateArgument::Expression); 418 } 419 420 TemplateArgumentLoc(const TemplateArgument &Argument, 421 NestedNameSpecifierLoc QualifierLoc, 422 SourceLocation TemplateNameLoc, 423 SourceLocation EllipsisLoc = SourceLocation()) 424 : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) { 425 assert(Argument.getKind() == TemplateArgument::Template || 426 Argument.getKind() == TemplateArgument::TemplateExpansion); 427 } 428 429 /// \brief - Fetches the primary location of the argument. 430 SourceLocation getLocation() const { 431 if (Argument.getKind() == TemplateArgument::Template || 432 Argument.getKind() == TemplateArgument::TemplateExpansion) 433 return getTemplateNameLoc(); 434 435 return getSourceRange().getBegin(); 436 } 437 438 /// \brief - Fetches the full source range of the argument. 439 SourceRange getSourceRange() const LLVM_READONLY; 440 441 const TemplateArgument &getArgument() const { 442 return Argument; 443 } 444 445 TemplateArgumentLocInfo getLocInfo() const { 446 return LocInfo; 447 } 448 449 TypeSourceInfo *getTypeSourceInfo() const { 450 assert(Argument.getKind() == TemplateArgument::Type); 451 return LocInfo.getAsTypeSourceInfo(); 452 } 453 454 Expr *getSourceExpression() const { 455 assert(Argument.getKind() == TemplateArgument::Expression); 456 return LocInfo.getAsExpr(); 457 } 458 459 Expr *getSourceDeclExpression() const { 460 assert(Argument.getKind() == TemplateArgument::Declaration); 461 return LocInfo.getAsExpr(); 462 } 463 464 Expr *getSourceNullPtrExpression() const { 465 assert(Argument.getKind() == TemplateArgument::NullPtr); 466 return LocInfo.getAsExpr(); 467 } 468 469 Expr *getSourceIntegralExpression() const { 470 assert(Argument.getKind() == TemplateArgument::Integral); 471 return LocInfo.getAsExpr(); 472 } 473 474 NestedNameSpecifierLoc getTemplateQualifierLoc() const { 475 assert(Argument.getKind() == TemplateArgument::Template || 476 Argument.getKind() == TemplateArgument::TemplateExpansion); 477 return LocInfo.getTemplateQualifierLoc(); 478 } 479 480 SourceLocation getTemplateNameLoc() const { 481 assert(Argument.getKind() == TemplateArgument::Template || 482 Argument.getKind() == TemplateArgument::TemplateExpansion); 483 return LocInfo.getTemplateNameLoc(); 484 } 485 486 SourceLocation getTemplateEllipsisLoc() const { 487 assert(Argument.getKind() == TemplateArgument::TemplateExpansion); 488 return LocInfo.getTemplateEllipsisLoc(); 489 } 490 491 /// \brief When the template argument is a pack expansion, returns 492 /// the pattern of the pack expansion. 493 /// 494 /// \param Ellipsis Will be set to the location of the ellipsis. 495 /// 496 /// \param NumExpansions Will be set to the number of expansions that will 497 /// be generated from this pack expansion, if known a priori. 498 TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis, 499 Optional<unsigned> &NumExpansions, 500 ASTContext &Context) const; 501}; 502 503/// A convenient class for passing around template argument 504/// information. Designed to be passed by reference. 505class TemplateArgumentListInfo { 506 SmallVector<TemplateArgumentLoc, 8> Arguments; 507 SourceLocation LAngleLoc; 508 SourceLocation RAngleLoc; 509 510 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo 511 // instead. 512 void* operator new(size_t bytes, ASTContext& C); 513 514public: 515 TemplateArgumentListInfo() {} 516 517 TemplateArgumentListInfo(SourceLocation LAngleLoc, 518 SourceLocation RAngleLoc) 519 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} 520 521 SourceLocation getLAngleLoc() const { return LAngleLoc; } 522 SourceLocation getRAngleLoc() const { return RAngleLoc; } 523 524 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } 525 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } 526 527 unsigned size() const { return Arguments.size(); } 528 529 const TemplateArgumentLoc *getArgumentArray() const { 530 return Arguments.data(); 531 } 532 533 const TemplateArgumentLoc &operator[](unsigned I) const { 534 return Arguments[I]; 535 } 536 537 void addArgument(const TemplateArgumentLoc &Loc) { 538 Arguments.push_back(Loc); 539 } 540}; 541 542/// \brief Represents an explicit template argument list in C++, e.g., 543/// the "<int>" in "sort<int>". 544/// This is safe to be used inside an AST node, in contrast with 545/// TemplateArgumentListInfo. 546struct ASTTemplateArgumentListInfo { 547 /// \brief The source location of the left angle bracket ('<'). 548 SourceLocation LAngleLoc; 549 550 /// \brief The source location of the right angle bracket ('>'). 551 SourceLocation RAngleLoc; 552 553 union { 554 /// \brief The number of template arguments in TemplateArgs. 555 /// The actual template arguments (if any) are stored after the 556 /// ExplicitTemplateArgumentList structure. 557 unsigned NumTemplateArgs; 558 559 /// Force ASTTemplateArgumentListInfo to the right alignment 560 /// for the following array of TemplateArgumentLocs. 561 void *Aligner; 562 }; 563 564 /// \brief Retrieve the template arguments 565 TemplateArgumentLoc *getTemplateArgs() { 566 return reinterpret_cast<TemplateArgumentLoc *> (this + 1); 567 } 568 569 /// \brief Retrieve the template arguments 570 const TemplateArgumentLoc *getTemplateArgs() const { 571 return reinterpret_cast<const TemplateArgumentLoc *> (this + 1); 572 } 573 574 const TemplateArgumentLoc &operator[](unsigned I) const { 575 return getTemplateArgs()[I]; 576 } 577 578 static const ASTTemplateArgumentListInfo *Create(ASTContext &C, 579 const TemplateArgumentListInfo &List); 580 581 void initializeFrom(const TemplateArgumentListInfo &List); 582 void initializeFrom(const TemplateArgumentListInfo &List, 583 bool &Dependent, bool &InstantiationDependent, 584 bool &ContainsUnexpandedParameterPack); 585 void copyInto(TemplateArgumentListInfo &List) const; 586 static std::size_t sizeFor(unsigned NumTemplateArgs); 587}; 588 589/// \brief Extends ASTTemplateArgumentListInfo with the source location 590/// information for the template keyword; this is used as part of the 591/// representation of qualified identifiers, such as S<T>::template apply<T>. 592struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo { 593 typedef ASTTemplateArgumentListInfo Base; 594 595 // NOTE: the source location of the (optional) template keyword is 596 // stored after all template arguments. 597 598 /// \brief Get the source location of the template keyword. 599 SourceLocation getTemplateKeywordLoc() const { 600 return *reinterpret_cast<const SourceLocation*> 601 (getTemplateArgs() + NumTemplateArgs); 602 } 603 604 /// \brief Sets the source location of the template keyword. 605 void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) { 606 *reinterpret_cast<SourceLocation*> 607 (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc; 608 } 609 610 static const ASTTemplateKWAndArgsInfo* 611 Create(ASTContext &C, SourceLocation TemplateKWLoc, 612 const TemplateArgumentListInfo &List); 613 614 void initializeFrom(SourceLocation TemplateKWLoc, 615 const TemplateArgumentListInfo &List); 616 void initializeFrom(SourceLocation TemplateKWLoc, 617 const TemplateArgumentListInfo &List, 618 bool &Dependent, bool &InstantiationDependent, 619 bool &ContainsUnexpandedParameterPack); 620 void initializeFrom(SourceLocation TemplateKWLoc); 621 622 static std::size_t sizeFor(unsigned NumTemplateArgs); 623}; 624 625const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 626 const TemplateArgument &Arg); 627 628inline TemplateSpecializationType::iterator 629 TemplateSpecializationType::end() const { 630 return getArgs() + getNumArgs(); 631} 632 633inline DependentTemplateSpecializationType::iterator 634 DependentTemplateSpecializationType::end() const { 635 return getArgs() + getNumArgs(); 636} 637 638inline const TemplateArgument & 639 TemplateSpecializationType::getArg(unsigned Idx) const { 640 assert(Idx < getNumArgs() && "Template argument out of range"); 641 return getArgs()[Idx]; 642} 643 644inline const TemplateArgument & 645 DependentTemplateSpecializationType::getArg(unsigned Idx) const { 646 assert(Idx < getNumArgs() && "Template argument out of range"); 647 return getArgs()[Idx]; 648} 649 650} // end namespace clang 651 652#endif 653