1 //===- TemplateName.cpp - C++ Template Name Representation ----------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the TemplateName interface and subclasses. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/AST/TemplateName.h" 14 #include "clang/AST/Decl.h" 15 #include "clang/AST/DeclBase.h" 16 #include "clang/AST/DeclCXX.h" 17 #include "clang/AST/DeclTemplate.h" 18 #include "clang/AST/DependenceFlags.h" 19 #include "clang/AST/NestedNameSpecifier.h" 20 #include "clang/AST/PrettyPrinter.h" 21 #include "clang/AST/TemplateBase.h" 22 #include "clang/Basic/Diagnostic.h" 23 #include "clang/Basic/LLVM.h" 24 #include "clang/Basic/LangOptions.h" 25 #include "clang/Basic/OperatorKinds.h" 26 #include "llvm/ADT/ArrayRef.h" 27 #include "llvm/ADT/FoldingSet.h" 28 #include "llvm/Support/Compiler.h" 29 #include "llvm/Support/raw_ostream.h" 30 #include <cassert> 31 #include <optional> 32 #include <string> 33 34 using namespace clang; 35 36 DeducedTemplateStorage::DeducedTemplateStorage(TemplateName Underlying, 37 const DefaultArguments &DefArgs) 38 : UncommonTemplateNameStorage(Deduced, /*Index=*/DefArgs.StartPos, 39 DefArgs.Args.size()), 40 Underlying(Underlying) { 41 llvm::copy(DefArgs.Args, reinterpret_cast<TemplateArgument *>(this + 1)); 42 } 43 44 void DeducedTemplateStorage::Profile(llvm::FoldingSetNodeID &ID, 45 const ASTContext &Context) const { 46 Profile(ID, Context, Underlying, getDefaultArguments()); 47 } 48 49 void DeducedTemplateStorage::Profile(llvm::FoldingSetNodeID &ID, 50 const ASTContext &Context, 51 TemplateName Underlying, 52 const DefaultArguments &DefArgs) { 53 Underlying.Profile(ID); 54 ID.AddInteger(DefArgs.StartPos); 55 ID.AddInteger(DefArgs.Args.size()); 56 for (const TemplateArgument &Arg : DefArgs.Args) 57 Arg.Profile(ID, Context); 58 } 59 60 TemplateArgument 61 SubstTemplateTemplateParmPackStorage::getArgumentPack() const { 62 return TemplateArgument(ArrayRef(Arguments, Bits.Data)); 63 } 64 65 TemplateTemplateParmDecl * 66 SubstTemplateTemplateParmPackStorage::getParameterPack() const { 67 return cast<TemplateTemplateParmDecl>( 68 getReplacedTemplateParameterList(getAssociatedDecl()) 69 ->asArray()[Bits.Index]); 70 } 71 72 TemplateTemplateParmDecl * 73 SubstTemplateTemplateParmStorage::getParameter() const { 74 return cast<TemplateTemplateParmDecl>( 75 getReplacedTemplateParameterList(getAssociatedDecl()) 76 ->asArray()[Bits.Index]); 77 } 78 79 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) { 80 Profile(ID, Replacement, getAssociatedDecl(), getIndex(), getPackIndex(), 81 getFinal()); 82 } 83 84 void SubstTemplateTemplateParmStorage::Profile( 85 llvm::FoldingSetNodeID &ID, TemplateName Replacement, Decl *AssociatedDecl, 86 unsigned Index, UnsignedOrNone PackIndex, bool Final) { 87 Replacement.Profile(ID); 88 ID.AddPointer(AssociatedDecl); 89 ID.AddInteger(Index); 90 ID.AddInteger(PackIndex.toInternalRepresentation()); 91 ID.AddBoolean(Final); 92 } 93 94 SubstTemplateTemplateParmPackStorage::SubstTemplateTemplateParmPackStorage( 95 ArrayRef<TemplateArgument> ArgPack, Decl *AssociatedDecl, unsigned Index, 96 bool Final) 97 : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Index, 98 ArgPack.size()), 99 Arguments(ArgPack.data()), AssociatedDeclAndFinal(AssociatedDecl, Final) { 100 assert(AssociatedDecl != nullptr); 101 } 102 103 void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID, 104 ASTContext &Context) { 105 Profile(ID, Context, getArgumentPack(), getAssociatedDecl(), getIndex(), 106 getFinal()); 107 } 108 109 Decl *SubstTemplateTemplateParmPackStorage::getAssociatedDecl() const { 110 return AssociatedDeclAndFinal.getPointer(); 111 } 112 113 bool SubstTemplateTemplateParmPackStorage::getFinal() const { 114 return AssociatedDeclAndFinal.getInt(); 115 } 116 117 void SubstTemplateTemplateParmPackStorage::Profile( 118 llvm::FoldingSetNodeID &ID, ASTContext &Context, 119 const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index, 120 bool Final) { 121 ArgPack.Profile(ID, Context); 122 ID.AddPointer(AssociatedDecl); 123 ID.AddInteger(Index); 124 ID.AddBoolean(Final); 125 } 126 127 IdentifierOrOverloadedOperator::IdentifierOrOverloadedOperator( 128 const IdentifierInfo *II) 129 : PtrOrOp(reinterpret_cast<uintptr_t>(II)) { 130 static_assert(NUM_OVERLOADED_OPERATORS <= 4096, 131 "NUM_OVERLOADED_OPERATORS is too large"); 132 assert(II); 133 assert(getIdentifier() == II); 134 } 135 IdentifierOrOverloadedOperator::IdentifierOrOverloadedOperator( 136 OverloadedOperatorKind OOK) 137 : PtrOrOp(-uintptr_t(OOK)) { 138 assert(OOK != OO_None); 139 assert(getOperator() == OOK); 140 } 141 142 void IdentifierOrOverloadedOperator::Profile(llvm::FoldingSetNodeID &ID) const { 143 if (auto *Identifier = getIdentifier()) { 144 ID.AddBoolean(false); 145 ID.AddPointer(Identifier); 146 } else { 147 ID.AddBoolean(true); 148 ID.AddInteger(getOperator()); 149 } 150 } 151 152 TemplateName::TemplateName(void *Ptr) { 153 Storage = StorageType::getFromOpaqueValue(Ptr); 154 } 155 156 TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {} 157 TemplateName::TemplateName(OverloadedTemplateStorage *Storage) 158 : Storage(Storage) {} 159 TemplateName::TemplateName(AssumedTemplateStorage *Storage) 160 : Storage(Storage) {} 161 TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage) 162 : Storage(Storage) {} 163 TemplateName::TemplateName(SubstTemplateTemplateParmPackStorage *Storage) 164 : Storage(Storage) {} 165 TemplateName::TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) {} 166 TemplateName::TemplateName(DependentTemplateName *Dep) : Storage(Dep) {} 167 TemplateName::TemplateName(UsingShadowDecl *Using) : Storage(Using) {} 168 TemplateName::TemplateName(DeducedTemplateStorage *Deduced) 169 : Storage(Deduced) {} 170 171 bool TemplateName::isNull() const { return Storage.isNull(); } 172 173 TemplateName::NameKind TemplateName::getKind() const { 174 if (auto *ND = dyn_cast<Decl *>(Storage)) { 175 if (isa<UsingShadowDecl>(ND)) 176 return UsingTemplate; 177 assert(isa<TemplateDecl>(ND)); 178 return Template; 179 } 180 181 if (isa<DependentTemplateName *>(Storage)) 182 return DependentTemplate; 183 if (isa<QualifiedTemplateName *>(Storage)) 184 return QualifiedTemplate; 185 186 UncommonTemplateNameStorage *uncommon = 187 cast<UncommonTemplateNameStorage *>(Storage); 188 if (uncommon->getAsOverloadedStorage()) 189 return OverloadedTemplate; 190 if (uncommon->getAsAssumedTemplateName()) 191 return AssumedTemplate; 192 if (uncommon->getAsSubstTemplateTemplateParm()) 193 return SubstTemplateTemplateParm; 194 if (uncommon->getAsDeducedTemplateName()) 195 return DeducedTemplate; 196 197 assert(uncommon->getAsSubstTemplateTemplateParmPack() != nullptr); 198 return SubstTemplateTemplateParmPack; 199 } 200 201 TemplateDecl *TemplateName::getAsTemplateDecl(bool IgnoreDeduced) const { 202 TemplateName Name = *this; 203 while (std::optional<TemplateName> UnderlyingOrNone = 204 Name.desugar(IgnoreDeduced)) 205 Name = *UnderlyingOrNone; 206 207 if (!IgnoreDeduced) 208 assert(Name.getAsDeducedTemplateName() == nullptr && 209 "Unexpected canonical DeducedTemplateName; Did you mean to use " 210 "getTemplateDeclAndDefaultArgs instead?"); 211 212 return cast_if_present<TemplateDecl>( 213 dyn_cast_if_present<Decl *>(Name.Storage)); 214 } 215 216 std::pair<TemplateDecl *, DefaultArguments> 217 TemplateName::getTemplateDeclAndDefaultArgs() const { 218 for (TemplateName Name = *this; /**/; /**/) { 219 if (Name.getKind() == TemplateName::DeducedTemplate) { 220 DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName(); 221 TemplateDecl *TD = 222 DTS->getUnderlying().getAsTemplateDecl(/*IgnoreDeduced=*/true); 223 DefaultArguments DefArgs = DTS->getDefaultArguments(); 224 if (TD && DefArgs) 225 assert(DefArgs.StartPos + DefArgs.Args.size() <= 226 TD->getTemplateParameters()->size()); 227 return {TD, DTS->getDefaultArguments()}; 228 } 229 if (std::optional<TemplateName> UnderlyingOrNone = 230 Name.desugar(/*IgnoreDeduced=*/false)) { 231 Name = *UnderlyingOrNone; 232 continue; 233 } 234 return {cast_if_present<TemplateDecl>(Name.Storage.dyn_cast<Decl *>()), {}}; 235 } 236 } 237 238 std::optional<TemplateName> TemplateName::desugar(bool IgnoreDeduced) const { 239 if (Decl *D = dyn_cast_if_present<Decl *>(Storage)) { 240 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 241 return TemplateName(USD->getTargetDecl()); 242 return std::nullopt; 243 } 244 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) 245 return QTN->getUnderlyingTemplate(); 246 if (SubstTemplateTemplateParmStorage *S = getAsSubstTemplateTemplateParm()) 247 return S->getReplacement(); 248 if (IgnoreDeduced) 249 if (DeducedTemplateStorage *S = getAsDeducedTemplateName()) 250 return S->getUnderlying(); 251 return std::nullopt; 252 } 253 254 OverloadedTemplateStorage *TemplateName::getAsOverloadedTemplate() const { 255 if (UncommonTemplateNameStorage *Uncommon = 256 Storage.dyn_cast<UncommonTemplateNameStorage *>()) 257 return Uncommon->getAsOverloadedStorage(); 258 259 return nullptr; 260 } 261 262 AssumedTemplateStorage *TemplateName::getAsAssumedTemplateName() const { 263 if (UncommonTemplateNameStorage *Uncommon = 264 Storage.dyn_cast<UncommonTemplateNameStorage *>()) 265 return Uncommon->getAsAssumedTemplateName(); 266 267 return nullptr; 268 } 269 270 SubstTemplateTemplateParmStorage * 271 TemplateName::getAsSubstTemplateTemplateParm() const { 272 if (UncommonTemplateNameStorage *uncommon = 273 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage)) 274 return uncommon->getAsSubstTemplateTemplateParm(); 275 276 return nullptr; 277 } 278 279 SubstTemplateTemplateParmPackStorage * 280 TemplateName::getAsSubstTemplateTemplateParmPack() const { 281 if (UncommonTemplateNameStorage *Uncommon = 282 Storage.dyn_cast<UncommonTemplateNameStorage *>()) 283 return Uncommon->getAsSubstTemplateTemplateParmPack(); 284 285 return nullptr; 286 } 287 288 QualifiedTemplateName *TemplateName::getAsQualifiedTemplateName() const { 289 return dyn_cast_if_present<QualifiedTemplateName *>(Storage); 290 } 291 292 DependentTemplateName *TemplateName::getAsDependentTemplateName() const { 293 return Storage.dyn_cast<DependentTemplateName *>(); 294 } 295 296 UsingShadowDecl *TemplateName::getAsUsingShadowDecl() const { 297 if (Decl *D = Storage.dyn_cast<Decl *>()) 298 if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) 299 return USD; 300 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) 301 return QTN->getUnderlyingTemplate().getAsUsingShadowDecl(); 302 return nullptr; 303 } 304 305 DependentTemplateStorage::DependentTemplateStorage( 306 NestedNameSpecifier *Qualifier, IdentifierOrOverloadedOperator Name, 307 bool HasTemplateKeyword) 308 : Qualifier(Qualifier, HasTemplateKeyword), Name(Name) { 309 assert((!Qualifier || Qualifier->isDependent()) && 310 "Qualifier must be dependent"); 311 } 312 313 TemplateNameDependence DependentTemplateStorage::getDependence() const { 314 auto D = TemplateNameDependence::DependentInstantiation; 315 if (NestedNameSpecifier *Qualifier = getQualifier()) 316 D |= toTemplateNameDependence(Qualifier->getDependence()); 317 return D; 318 } 319 320 void DependentTemplateStorage::print(raw_ostream &OS, 321 const PrintingPolicy &Policy) const { 322 if (NestedNameSpecifier *NNS = getQualifier()) 323 NNS->print(OS, Policy); 324 325 if (hasTemplateKeyword()) 326 OS << "template "; 327 328 IdentifierOrOverloadedOperator Name = getName(); 329 if (const IdentifierInfo *II = Name.getIdentifier()) 330 OS << II->getName(); 331 else 332 OS << "operator " << getOperatorSpelling(Name.getOperator()); 333 } 334 335 DeducedTemplateStorage *TemplateName::getAsDeducedTemplateName() const { 336 if (UncommonTemplateNameStorage *Uncommon = 337 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage)) 338 return Uncommon->getAsDeducedTemplateName(); 339 340 return nullptr; 341 } 342 343 TemplateNameDependence TemplateName::getDependence() const { 344 switch (getKind()) { 345 case NameKind::Template: 346 case NameKind::UsingTemplate: { 347 TemplateDecl *Template = getAsTemplateDecl(); 348 auto D = TemplateNameDependence::None; 349 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) { 350 D |= TemplateNameDependence::DependentInstantiation; 351 if (TTP->isParameterPack()) 352 D |= TemplateNameDependence::UnexpandedPack; 353 } 354 // FIXME: Hack, getDeclContext() can be null if Template is still 355 // initializing due to PCH reading, so we check it before using it. 356 // Should probably modify TemplateSpecializationType to allow constructing 357 // it without the isDependent() checking. 358 if (Template->getDeclContext() && 359 Template->getDeclContext()->isDependentContext()) 360 D |= TemplateNameDependence::DependentInstantiation; 361 return D; 362 } 363 case NameKind::QualifiedTemplate: { 364 QualifiedTemplateName *S = getAsQualifiedTemplateName(); 365 TemplateNameDependence D = S->getUnderlyingTemplate().getDependence(); 366 if (NestedNameSpecifier *NNS = S->getQualifier()) 367 D |= toTemplateNameDependence(NNS->getDependence()); 368 return D; 369 } 370 case NameKind::DependentTemplate: { 371 DependentTemplateName *S = getAsDependentTemplateName(); 372 auto D = TemplateNameDependence::DependentInstantiation; 373 if (NestedNameSpecifier *Qualifier = S->getQualifier()) 374 D |= toTemplateNameDependence(Qualifier->getDependence()); 375 return D; 376 } 377 case NameKind::SubstTemplateTemplateParm: { 378 auto *S = getAsSubstTemplateTemplateParm(); 379 return S->getReplacement().getDependence(); 380 } 381 case NameKind::SubstTemplateTemplateParmPack: 382 return TemplateNameDependence::UnexpandedPack | 383 TemplateNameDependence::DependentInstantiation; 384 case NameKind::DeducedTemplate: { 385 DeducedTemplateStorage *DTS = getAsDeducedTemplateName(); 386 TemplateNameDependence D = DTS->getUnderlying().getDependence(); 387 for (const TemplateArgument &Arg : DTS->getDefaultArguments().Args) 388 D |= toTemplateNameDependence(Arg.getDependence()); 389 return D; 390 } 391 case NameKind::AssumedTemplate: 392 return TemplateNameDependence::DependentInstantiation; 393 case NameKind::OverloadedTemplate: 394 llvm_unreachable("overloaded templates shouldn't survive to here."); 395 } 396 llvm_unreachable("Unknown TemplateName kind"); 397 } 398 399 bool TemplateName::isDependent() const { 400 return getDependence() & TemplateNameDependence::Dependent; 401 } 402 403 bool TemplateName::isInstantiationDependent() const { 404 return getDependence() & TemplateNameDependence::Instantiation; 405 } 406 407 bool TemplateName::containsUnexpandedParameterPack() const { 408 return getDependence() & TemplateNameDependence::UnexpandedPack; 409 } 410 411 void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy, 412 Qualified Qual) const { 413 auto handleAnonymousTTP = [&](TemplateDecl *TD, raw_ostream &OS) { 414 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(TD); 415 TTP && (Policy.PrintAsCanonical || TTP->getIdentifier() == nullptr)) { 416 OS << "template-parameter-" << TTP->getDepth() << "-" << TTP->getIndex(); 417 return true; 418 } 419 return false; 420 }; 421 if (NameKind Kind = getKind(); 422 Kind == TemplateName::Template || Kind == TemplateName::UsingTemplate) { 423 // After `namespace ns { using std::vector }`, what is the fully-qualified 424 // name of the UsingTemplateName `vector` within ns? 425 // 426 // - ns::vector (the qualified name of the using-shadow decl) 427 // - std::vector (the qualified name of the underlying template decl) 428 // 429 // Similar to the UsingType behavior, using declarations are used to import 430 // names more often than to export them, thus using the original name is 431 // most useful in this case. 432 TemplateDecl *Template = getAsTemplateDecl(); 433 if (Policy.PrintAsCanonical) 434 Template = cast<TemplateDecl>(Template->getCanonicalDecl()); 435 if (handleAnonymousTTP(Template, OS)) 436 return; 437 if (Qual == Qualified::None) 438 OS << *Template; 439 else 440 Template->printQualifiedName(OS, Policy); 441 } else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { 442 if (Policy.PrintAsCanonical) { 443 QTN->getUnderlyingTemplate().print(OS, Policy, Qual); 444 return; 445 } 446 if (NestedNameSpecifier *NNS = QTN->getQualifier(); 447 Qual != Qualified::None && NNS) 448 NNS->print(OS, Policy); 449 if (QTN->hasTemplateKeyword()) 450 OS << "template "; 451 452 TemplateName Underlying = QTN->getUnderlyingTemplate(); 453 assert(Underlying.getKind() == TemplateName::Template || 454 Underlying.getKind() == TemplateName::UsingTemplate); 455 456 TemplateDecl *UTD = Underlying.getAsTemplateDecl(); 457 458 if (handleAnonymousTTP(UTD, OS)) 459 return; 460 461 if (IdentifierInfo *II = UTD->getIdentifier(); 462 Policy.CleanUglifiedParameters && II && 463 isa<TemplateTemplateParmDecl>(UTD)) 464 OS << II->deuglifiedName(); 465 else 466 OS << *UTD; 467 } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) { 468 DTN->print(OS, Policy); 469 } else if (SubstTemplateTemplateParmStorage *subst = 470 getAsSubstTemplateTemplateParm()) { 471 subst->getReplacement().print(OS, Policy, Qual); 472 } else if (SubstTemplateTemplateParmPackStorage *SubstPack = 473 getAsSubstTemplateTemplateParmPack()) 474 OS << *SubstPack->getParameterPack(); 475 else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) { 476 Assumed->getDeclName().print(OS, Policy); 477 } else if (DeducedTemplateStorage *Deduced = getAsDeducedTemplateName()) { 478 Deduced->getUnderlying().print(OS, Policy); 479 DefaultArguments DefArgs = Deduced->getDefaultArguments(); 480 OS << ":" << DefArgs.StartPos; 481 printTemplateArgumentList(OS, DefArgs.Args, Policy); 482 } else { 483 assert(getKind() == TemplateName::OverloadedTemplate); 484 OverloadedTemplateStorage *OTS = getAsOverloadedTemplate(); 485 (*OTS->begin())->printName(OS, Policy); 486 } 487 } 488 489 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB, 490 TemplateName N) { 491 std::string NameStr; 492 llvm::raw_string_ostream OS(NameStr); 493 LangOptions LO; 494 LO.CPlusPlus = true; 495 LO.Bool = true; 496 OS << '\''; 497 N.print(OS, PrintingPolicy(LO)); 498 OS << '\''; 499 return DB << NameStr; 500 } 501