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