1 //===- SemaTemplate.h - 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 // This file provides types used in the semantic analysis of C++ templates. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_SEMA_TEMPLATE_H 14 #define LLVM_CLANG_SEMA_TEMPLATE_H 15 16 #include "clang/AST/DeclTemplate.h" 17 #include "clang/AST/DeclVisitor.h" 18 #include "clang/AST/TemplateBase.h" 19 #include "clang/AST/Type.h" 20 #include "clang/Basic/LLVM.h" 21 #include "clang/Sema/Sema.h" 22 #include "llvm/ADT/ArrayRef.h" 23 #include "llvm/ADT/DenseMap.h" 24 #include "llvm/ADT/PointerUnion.h" 25 #include "llvm/ADT/SmallVector.h" 26 #include <cassert> 27 #include <utility> 28 29 namespace clang { 30 31 class ASTContext; 32 class BindingDecl; 33 class CXXMethodDecl; 34 class Decl; 35 class DeclaratorDecl; 36 class DeclContext; 37 class EnumDecl; 38 class FunctionDecl; 39 class NamedDecl; 40 class ParmVarDecl; 41 class TagDecl; 42 class TypedefNameDecl; 43 class TypeSourceInfo; 44 class VarDecl; 45 46 /// Data structure that captures multiple levels of template argument 47 /// lists for use in template instantiation. 48 /// 49 /// Multiple levels of template arguments occur when instantiating the 50 /// definitions of member templates. For example: 51 /// 52 /// \code 53 /// template<typename T> 54 /// struct X { 55 /// template<T Value> 56 /// struct Y { 57 /// void f(); 58 /// }; 59 /// }; 60 /// \endcode 61 /// 62 /// When instantiating X<int>::Y<17>::f, the multi-level template argument 63 /// list will contain a template argument list (int) at depth 0 and a 64 /// template argument list (17) at depth 1. 65 class MultiLevelTemplateArgumentList { 66 /// The template argument list at a certain template depth 67 using ArgList = ArrayRef<TemplateArgument>; 68 69 /// The template argument lists, stored from the innermost template 70 /// argument list (first) to the outermost template argument list (last). 71 SmallVector<ArgList, 4> TemplateArgumentLists; 72 73 /// The number of outer levels of template arguments that are not 74 /// being substituted. 75 unsigned NumRetainedOuterLevels = 0; 76 77 public: 78 /// Construct an empty set of template argument lists. 79 MultiLevelTemplateArgumentList() = default; 80 81 /// Construct a single-level template argument list. 82 explicit MultiLevelTemplateArgumentList(const TemplateArgumentList & TemplateArgs)83 MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) { 84 addOuterTemplateArguments(&TemplateArgs); 85 } 86 87 /// Determine the number of levels in this template argument 88 /// list. getNumLevels()89 unsigned getNumLevels() const { 90 return TemplateArgumentLists.size() + NumRetainedOuterLevels; 91 } 92 93 /// Determine the number of substituted levels in this template 94 /// argument list. getNumSubstitutedLevels()95 unsigned getNumSubstitutedLevels() const { 96 return TemplateArgumentLists.size(); 97 } 98 99 /// Retrieve the template argument at a given depth and index. operator()100 const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { 101 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 102 assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); 103 return TemplateArgumentLists[getNumLevels() - Depth - 1][Index]; 104 } 105 106 /// Determine whether there is a non-NULL template argument at the 107 /// given depth and index. 108 /// 109 /// There must exist a template argument list at the given depth. hasTemplateArgument(unsigned Depth,unsigned Index)110 bool hasTemplateArgument(unsigned Depth, unsigned Index) const { 111 assert(Depth < getNumLevels()); 112 113 if (Depth < NumRetainedOuterLevels) 114 return false; 115 116 if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size()) 117 return false; 118 119 return !(*this)(Depth, Index).isNull(); 120 } 121 122 /// Clear out a specific template argument. setArgument(unsigned Depth,unsigned Index,TemplateArgument Arg)123 void setArgument(unsigned Depth, unsigned Index, 124 TemplateArgument Arg) { 125 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 126 assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); 127 const_cast<TemplateArgument&>( 128 TemplateArgumentLists[getNumLevels() - Depth - 1][Index]) 129 = Arg; 130 } 131 132 /// Add a new outermost level to the multi-level template argument 133 /// list. addOuterTemplateArguments(const TemplateArgumentList * TemplateArgs)134 void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { 135 addOuterTemplateArguments(ArgList(TemplateArgs->data(), 136 TemplateArgs->size())); 137 } 138 139 /// Add a new outmost level to the multi-level template argument 140 /// list. addOuterTemplateArguments(ArgList Args)141 void addOuterTemplateArguments(ArgList Args) { 142 assert(!NumRetainedOuterLevels && 143 "substituted args outside retained args?"); 144 TemplateArgumentLists.push_back(Args); 145 } 146 147 /// Add an outermost level that we are not substituting. We have no 148 /// arguments at this level, and do not remove it from the depth of inner 149 /// template parameters that we instantiate. addOuterRetainedLevel()150 void addOuterRetainedLevel() { 151 ++NumRetainedOuterLevels; 152 } 153 154 /// Retrieve the innermost template argument list. getInnermost()155 const ArgList &getInnermost() const { 156 return TemplateArgumentLists.front(); 157 } 158 }; 159 160 /// The context in which partial ordering of function templates occurs. 161 enum TPOC { 162 /// Partial ordering of function templates for a function call. 163 TPOC_Call, 164 165 /// Partial ordering of function templates for a call to a 166 /// conversion function. 167 TPOC_Conversion, 168 169 /// Partial ordering of function templates in other contexts, e.g., 170 /// taking the address of a function template or matching a function 171 /// template specialization to a function template. 172 TPOC_Other 173 }; 174 175 // This is lame but unavoidable in a world without forward 176 // declarations of enums. The alternatives are to either pollute 177 // Sema.h (by including this file) or sacrifice type safety (by 178 // making Sema.h declare things as enums). 179 class TemplatePartialOrderingContext { 180 TPOC Value; 181 182 public: TemplatePartialOrderingContext(TPOC Value)183 TemplatePartialOrderingContext(TPOC Value) : Value(Value) {} 184 TPOC()185 operator TPOC() const { return Value; } 186 }; 187 188 /// Captures a template argument whose value has been deduced 189 /// via c++ template argument deduction. 190 class DeducedTemplateArgument : public TemplateArgument { 191 /// For a non-type template argument, whether the value was 192 /// deduced from an array bound. 193 bool DeducedFromArrayBound = false; 194 195 public: 196 DeducedTemplateArgument() = default; 197 198 DeducedTemplateArgument(const TemplateArgument &Arg, 199 bool DeducedFromArrayBound = false) TemplateArgument(Arg)200 : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {} 201 202 /// Construct an integral non-type template argument that 203 /// has been deduced, possibly from an array bound. DeducedTemplateArgument(ASTContext & Ctx,const llvm::APSInt & Value,QualType ValueType,bool DeducedFromArrayBound)204 DeducedTemplateArgument(ASTContext &Ctx, 205 const llvm::APSInt &Value, 206 QualType ValueType, 207 bool DeducedFromArrayBound) 208 : TemplateArgument(Ctx, Value, ValueType), 209 DeducedFromArrayBound(DeducedFromArrayBound) {} 210 211 /// For a non-type template argument, determine whether the 212 /// template argument was deduced from an array bound. wasDeducedFromArrayBound()213 bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; } 214 215 /// Specify whether the given non-type template argument 216 /// was deduced from an array bound. setDeducedFromArrayBound(bool Deduced)217 void setDeducedFromArrayBound(bool Deduced) { 218 DeducedFromArrayBound = Deduced; 219 } 220 }; 221 222 /// A stack-allocated class that identifies which local 223 /// variable declaration instantiations are present in this scope. 224 /// 225 /// A new instance of this class type will be created whenever we 226 /// instantiate a new function declaration, which will have its own 227 /// set of parameter declarations. 228 class LocalInstantiationScope { 229 public: 230 /// A set of declarations. 231 using DeclArgumentPack = SmallVector<ParmVarDecl *, 4>; 232 233 private: 234 /// Reference to the semantic analysis that is performing 235 /// this template instantiation. 236 Sema &SemaRef; 237 238 using LocalDeclsMap = 239 llvm::SmallDenseMap<const Decl *, 240 llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>; 241 242 /// A mapping from local declarations that occur 243 /// within a template to their instantiations. 244 /// 245 /// This mapping is used during instantiation to keep track of, 246 /// e.g., function parameter and variable declarations. For example, 247 /// given: 248 /// 249 /// \code 250 /// template<typename T> T add(T x, T y) { return x + y; } 251 /// \endcode 252 /// 253 /// when we instantiate add<int>, we will introduce a mapping from 254 /// the ParmVarDecl for 'x' that occurs in the template to the 255 /// instantiated ParmVarDecl for 'x'. 256 /// 257 /// For a parameter pack, the local instantiation scope may contain a 258 /// set of instantiated parameters. This is stored as a DeclArgumentPack 259 /// pointer. 260 LocalDeclsMap LocalDecls; 261 262 /// The set of argument packs we've allocated. 263 SmallVector<DeclArgumentPack *, 1> ArgumentPacks; 264 265 /// The outer scope, which contains local variable 266 /// definitions from some other instantiation (that may not be 267 /// relevant to this particular scope). 268 LocalInstantiationScope *Outer; 269 270 /// Whether we have already exited this scope. 271 bool Exited = false; 272 273 /// Whether to combine this scope with the outer scope, such that 274 /// lookup will search our outer scope. 275 bool CombineWithOuterScope; 276 277 /// If non-NULL, the template parameter pack that has been 278 /// partially substituted per C++0x [temp.arg.explicit]p9. 279 NamedDecl *PartiallySubstitutedPack = nullptr; 280 281 /// If \c PartiallySubstitutedPack is non-null, the set of 282 /// explicitly-specified template arguments in that pack. 283 const TemplateArgument *ArgsInPartiallySubstitutedPack; 284 285 /// If \c PartiallySubstitutedPack, the number of 286 /// explicitly-specified template arguments in 287 /// ArgsInPartiallySubstitutedPack. 288 unsigned NumArgsInPartiallySubstitutedPack; 289 290 public: 291 LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) SemaRef(SemaRef)292 : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), 293 CombineWithOuterScope(CombineWithOuterScope) { 294 SemaRef.CurrentInstantiationScope = this; 295 } 296 297 LocalInstantiationScope(const LocalInstantiationScope &) = delete; 298 LocalInstantiationScope & 299 operator=(const LocalInstantiationScope &) = delete; 300 ~LocalInstantiationScope()301 ~LocalInstantiationScope() { 302 Exit(); 303 } 304 getSema()305 const Sema &getSema() const { return SemaRef; } 306 307 /// Exit this local instantiation scope early. Exit()308 void Exit() { 309 if (Exited) 310 return; 311 312 for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I) 313 delete ArgumentPacks[I]; 314 315 SemaRef.CurrentInstantiationScope = Outer; 316 Exited = true; 317 } 318 319 /// Clone this scope, and all outer scopes, down to the given 320 /// outermost scope. cloneScopes(LocalInstantiationScope * Outermost)321 LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) { 322 if (this == Outermost) return this; 323 324 // Save the current scope from SemaRef since the LocalInstantiationScope 325 // will overwrite it on construction 326 LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope; 327 328 LocalInstantiationScope *newScope = 329 new LocalInstantiationScope(SemaRef, CombineWithOuterScope); 330 331 newScope->Outer = nullptr; 332 if (Outer) 333 newScope->Outer = Outer->cloneScopes(Outermost); 334 335 newScope->PartiallySubstitutedPack = PartiallySubstitutedPack; 336 newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack; 337 newScope->NumArgsInPartiallySubstitutedPack = 338 NumArgsInPartiallySubstitutedPack; 339 340 for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end(); 341 I != E; ++I) { 342 const Decl *D = I->first; 343 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = 344 newScope->LocalDecls[D]; 345 if (I->second.is<Decl *>()) { 346 Stored = I->second.get<Decl *>(); 347 } else { 348 DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>(); 349 DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack); 350 Stored = NewPack; 351 newScope->ArgumentPacks.push_back(NewPack); 352 } 353 } 354 // Restore the saved scope to SemaRef 355 SemaRef.CurrentInstantiationScope = oldScope; 356 return newScope; 357 } 358 359 /// deletes the given scope, and all otuer scopes, down to the 360 /// given outermost scope. deleteScopes(LocalInstantiationScope * Scope,LocalInstantiationScope * Outermost)361 static void deleteScopes(LocalInstantiationScope *Scope, 362 LocalInstantiationScope *Outermost) { 363 while (Scope && Scope != Outermost) { 364 LocalInstantiationScope *Out = Scope->Outer; 365 delete Scope; 366 Scope = Out; 367 } 368 } 369 370 /// Find the instantiation of the declaration D within the current 371 /// instantiation scope. 372 /// 373 /// \param D The declaration whose instantiation we are searching for. 374 /// 375 /// \returns A pointer to the declaration or argument pack of declarations 376 /// to which the declaration \c D is instantiated, if found. Otherwise, 377 /// returns NULL. 378 llvm::PointerUnion<Decl *, DeclArgumentPack *> * 379 findInstantiationOf(const Decl *D); 380 381 void InstantiatedLocal(const Decl *D, Decl *Inst); 382 void InstantiatedLocalPackArg(const Decl *D, ParmVarDecl *Inst); 383 void MakeInstantiatedLocalArgPack(const Decl *D); 384 385 /// Note that the given parameter pack has been partially substituted 386 /// via explicit specification of template arguments 387 /// (C++0x [temp.arg.explicit]p9). 388 /// 389 /// \param Pack The parameter pack, which will always be a template 390 /// parameter pack. 391 /// 392 /// \param ExplicitArgs The explicitly-specified template arguments provided 393 /// for this parameter pack. 394 /// 395 /// \param NumExplicitArgs The number of explicitly-specified template 396 /// arguments provided for this parameter pack. 397 void SetPartiallySubstitutedPack(NamedDecl *Pack, 398 const TemplateArgument *ExplicitArgs, 399 unsigned NumExplicitArgs); 400 401 /// Reset the partially-substituted pack when it is no longer of 402 /// interest. ResetPartiallySubstitutedPack()403 void ResetPartiallySubstitutedPack() { 404 assert(PartiallySubstitutedPack && "No partially-substituted pack"); 405 PartiallySubstitutedPack = nullptr; 406 ArgsInPartiallySubstitutedPack = nullptr; 407 NumArgsInPartiallySubstitutedPack = 0; 408 } 409 410 /// Retrieve the partially-substitued template parameter pack. 411 /// 412 /// If there is no partially-substituted parameter pack, returns NULL. 413 NamedDecl * 414 getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, 415 unsigned *NumExplicitArgs = nullptr) const; 416 }; 417 418 class TemplateDeclInstantiator 419 : public DeclVisitor<TemplateDeclInstantiator, Decl *> 420 { 421 Sema &SemaRef; 422 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex; 423 DeclContext *Owner; 424 const MultiLevelTemplateArgumentList &TemplateArgs; 425 Sema::LateInstantiatedAttrVec* LateAttrs = nullptr; 426 LocalInstantiationScope *StartingScope = nullptr; 427 428 /// A list of out-of-line class template partial 429 /// specializations that will need to be instantiated after the 430 /// enclosing class's instantiation is complete. 431 SmallVector<std::pair<ClassTemplateDecl *, 432 ClassTemplatePartialSpecializationDecl *>, 4> 433 OutOfLinePartialSpecs; 434 435 /// A list of out-of-line variable template partial 436 /// specializations that will need to be instantiated after the 437 /// enclosing variable's instantiation is complete. 438 /// FIXME: Verify that this is needed. 439 SmallVector< 440 std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4> 441 OutOfLineVarPartialSpecs; 442 443 public: TemplateDeclInstantiator(Sema & SemaRef,DeclContext * Owner,const MultiLevelTemplateArgumentList & TemplateArgs)444 TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, 445 const MultiLevelTemplateArgumentList &TemplateArgs) 446 : SemaRef(SemaRef), 447 SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex), 448 Owner(Owner), TemplateArgs(TemplateArgs) {} 449 450 // Define all the decl visitors using DeclNodes.inc 451 #define DECL(DERIVED, BASE) \ 452 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); 453 #define ABSTRACT_DECL(DECL) 454 455 // Decls which never appear inside a class or function. 456 #define OBJCCONTAINER(DERIVED, BASE) 457 #define FILESCOPEASM(DERIVED, BASE) 458 #define IMPORT(DERIVED, BASE) 459 #define EXPORT(DERIVED, BASE) 460 #define LINKAGESPEC(DERIVED, BASE) 461 #define OBJCCOMPATIBLEALIAS(DERIVED, BASE) 462 #define OBJCMETHOD(DERIVED, BASE) 463 #define OBJCTYPEPARAM(DERIVED, BASE) 464 #define OBJCIVAR(DERIVED, BASE) 465 #define OBJCPROPERTY(DERIVED, BASE) 466 #define OBJCPROPERTYIMPL(DERIVED, BASE) 467 #define EMPTY(DERIVED, BASE) 468 469 // Decls which use special-case instantiation code. 470 #define BLOCK(DERIVED, BASE) 471 #define CAPTURED(DERIVED, BASE) 472 #define IMPLICITPARAM(DERIVED, BASE) 473 474 #include "clang/AST/DeclNodes.inc" 475 476 // A few supplemental visitor functions. 477 Decl *VisitCXXMethodDecl(CXXMethodDecl *D, 478 TemplateParameterList *TemplateParams, 479 bool IsClassScopeSpecialization = false); 480 Decl *VisitFunctionDecl(FunctionDecl *D, 481 TemplateParameterList *TemplateParams); 482 Decl *VisitDecl(Decl *D); 483 Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, 484 ArrayRef<BindingDecl *> *Bindings = nullptr); 485 486 // Enable late instantiation of attributes. Late instantiated attributes 487 // will be stored in LA. enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec * LA)488 void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { 489 LateAttrs = LA; 490 StartingScope = SemaRef.CurrentInstantiationScope; 491 } 492 493 // Disable late instantiation of attributes. disableLateAttributeInstantiation()494 void disableLateAttributeInstantiation() { 495 LateAttrs = nullptr; 496 StartingScope = nullptr; 497 } 498 getStartingScope()499 LocalInstantiationScope *getStartingScope() const { return StartingScope; } 500 501 using delayed_partial_spec_iterator = SmallVectorImpl<std::pair< 502 ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator; 503 504 using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair< 505 VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator; 506 507 /// Return an iterator to the beginning of the set of 508 /// "delayed" partial specializations, which must be passed to 509 /// InstantiateClassTemplatePartialSpecialization once the class 510 /// definition has been completed. delayed_partial_spec_begin()511 delayed_partial_spec_iterator delayed_partial_spec_begin() { 512 return OutOfLinePartialSpecs.begin(); 513 } 514 delayed_var_partial_spec_begin()515 delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { 516 return OutOfLineVarPartialSpecs.begin(); 517 } 518 519 /// Return an iterator to the end of the set of 520 /// "delayed" partial specializations, which must be passed to 521 /// InstantiateClassTemplatePartialSpecialization once the class 522 /// definition has been completed. delayed_partial_spec_end()523 delayed_partial_spec_iterator delayed_partial_spec_end() { 524 return OutOfLinePartialSpecs.end(); 525 } 526 delayed_var_partial_spec_end()527 delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { 528 return OutOfLineVarPartialSpecs.end(); 529 } 530 531 // Helper functions for instantiating methods. 532 TypeSourceInfo *SubstFunctionType(FunctionDecl *D, 533 SmallVectorImpl<ParmVarDecl *> &Params); 534 bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); 535 bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); 536 537 TemplateParameterList * 538 SubstTemplateParams(TemplateParameterList *List); 539 540 bool SubstQualifier(const DeclaratorDecl *OldDecl, 541 DeclaratorDecl *NewDecl); 542 bool SubstQualifier(const TagDecl *OldDecl, 543 TagDecl *NewDecl); 544 545 Decl *VisitVarTemplateSpecializationDecl( 546 VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos, 547 const TemplateArgumentListInfo &TemplateArgsInfo, 548 ArrayRef<TemplateArgument> Converted); 549 550 Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); 551 ClassTemplatePartialSpecializationDecl * 552 InstantiateClassTemplatePartialSpecialization( 553 ClassTemplateDecl *ClassTemplate, 554 ClassTemplatePartialSpecializationDecl *PartialSpec); 555 VarTemplatePartialSpecializationDecl * 556 InstantiateVarTemplatePartialSpecialization( 557 VarTemplateDecl *VarTemplate, 558 VarTemplatePartialSpecializationDecl *PartialSpec); 559 void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); 560 561 private: 562 template<typename T> 563 Decl *instantiateUnresolvedUsingDecl(T *D, 564 bool InstantiatingPackElement = false); 565 }; 566 567 } // namespace clang 568 569 #endif // LLVM_CLANG_SEMA_TEMPLATE_H 570