17330f729Sjoerg //===- TemplateName.cpp - C++ Template Name Representation ----------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file defines the TemplateName interface and subclasses.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg #include "clang/AST/TemplateName.h"
14*e038c9c4Sjoerg #include "clang/AST/Decl.h"
157330f729Sjoerg #include "clang/AST/DeclBase.h"
167330f729Sjoerg #include "clang/AST/DeclTemplate.h"
17*e038c9c4Sjoerg #include "clang/AST/DependenceFlags.h"
187330f729Sjoerg #include "clang/AST/NestedNameSpecifier.h"
197330f729Sjoerg #include "clang/AST/PrettyPrinter.h"
207330f729Sjoerg #include "clang/AST/TemplateBase.h"
217330f729Sjoerg #include "clang/Basic/Diagnostic.h"
227330f729Sjoerg #include "clang/Basic/LLVM.h"
237330f729Sjoerg #include "clang/Basic/LangOptions.h"
247330f729Sjoerg #include "clang/Basic/OperatorKinds.h"
257330f729Sjoerg #include "llvm/ADT/ArrayRef.h"
267330f729Sjoerg #include "llvm/ADT/FoldingSet.h"
277330f729Sjoerg #include "llvm/Support/Casting.h"
287330f729Sjoerg #include "llvm/Support/Compiler.h"
297330f729Sjoerg #include "llvm/Support/raw_ostream.h"
307330f729Sjoerg #include <cassert>
317330f729Sjoerg #include <string>
327330f729Sjoerg
337330f729Sjoerg using namespace clang;
347330f729Sjoerg
357330f729Sjoerg TemplateArgument
getArgumentPack() const367330f729Sjoerg SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
377330f729Sjoerg return TemplateArgument(llvm::makeArrayRef(Arguments, size()));
387330f729Sjoerg }
397330f729Sjoerg
Profile(llvm::FoldingSetNodeID & ID)407330f729Sjoerg void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
417330f729Sjoerg Profile(ID, Parameter, Replacement);
427330f729Sjoerg }
437330f729Sjoerg
Profile(llvm::FoldingSetNodeID & ID,TemplateTemplateParmDecl * parameter,TemplateName replacement)447330f729Sjoerg void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
457330f729Sjoerg TemplateTemplateParmDecl *parameter,
467330f729Sjoerg TemplateName replacement) {
477330f729Sjoerg ID.AddPointer(parameter);
487330f729Sjoerg ID.AddPointer(replacement.getAsVoidPointer());
497330f729Sjoerg }
507330f729Sjoerg
Profile(llvm::FoldingSetNodeID & ID,ASTContext & Context)517330f729Sjoerg void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
527330f729Sjoerg ASTContext &Context) {
537330f729Sjoerg Profile(ID, Context, Parameter, getArgumentPack());
547330f729Sjoerg }
557330f729Sjoerg
Profile(llvm::FoldingSetNodeID & ID,ASTContext & Context,TemplateTemplateParmDecl * Parameter,const TemplateArgument & ArgPack)567330f729Sjoerg void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
577330f729Sjoerg ASTContext &Context,
587330f729Sjoerg TemplateTemplateParmDecl *Parameter,
597330f729Sjoerg const TemplateArgument &ArgPack) {
607330f729Sjoerg ID.AddPointer(Parameter);
617330f729Sjoerg ArgPack.Profile(ID, Context);
627330f729Sjoerg }
637330f729Sjoerg
TemplateName(void * Ptr)647330f729Sjoerg TemplateName::TemplateName(void *Ptr) {
657330f729Sjoerg Storage = StorageType::getFromOpaqueValue(Ptr);
667330f729Sjoerg }
677330f729Sjoerg
TemplateName(TemplateDecl * Template)687330f729Sjoerg TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
TemplateName(OverloadedTemplateStorage * Storage)697330f729Sjoerg TemplateName::TemplateName(OverloadedTemplateStorage *Storage)
707330f729Sjoerg : Storage(Storage) {}
TemplateName(AssumedTemplateStorage * Storage)717330f729Sjoerg TemplateName::TemplateName(AssumedTemplateStorage *Storage)
727330f729Sjoerg : Storage(Storage) {}
TemplateName(SubstTemplateTemplateParmStorage * Storage)737330f729Sjoerg TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
747330f729Sjoerg : Storage(Storage) {}
TemplateName(SubstTemplateTemplateParmPackStorage * Storage)757330f729Sjoerg TemplateName::TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
767330f729Sjoerg : Storage(Storage) {}
TemplateName(QualifiedTemplateName * Qual)777330f729Sjoerg TemplateName::TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) {}
TemplateName(DependentTemplateName * Dep)787330f729Sjoerg TemplateName::TemplateName(DependentTemplateName *Dep) : Storage(Dep) {}
797330f729Sjoerg
isNull() const807330f729Sjoerg bool TemplateName::isNull() const { return Storage.isNull(); }
817330f729Sjoerg
getKind() const827330f729Sjoerg TemplateName::NameKind TemplateName::getKind() const {
837330f729Sjoerg if (Storage.is<TemplateDecl *>())
847330f729Sjoerg return Template;
857330f729Sjoerg if (Storage.is<DependentTemplateName *>())
867330f729Sjoerg return DependentTemplate;
877330f729Sjoerg if (Storage.is<QualifiedTemplateName *>())
887330f729Sjoerg return QualifiedTemplate;
897330f729Sjoerg
907330f729Sjoerg UncommonTemplateNameStorage *uncommon
917330f729Sjoerg = Storage.get<UncommonTemplateNameStorage*>();
927330f729Sjoerg if (uncommon->getAsOverloadedStorage())
937330f729Sjoerg return OverloadedTemplate;
947330f729Sjoerg if (uncommon->getAsAssumedTemplateName())
957330f729Sjoerg return AssumedTemplate;
967330f729Sjoerg if (uncommon->getAsSubstTemplateTemplateParm())
977330f729Sjoerg return SubstTemplateTemplateParm;
987330f729Sjoerg return SubstTemplateTemplateParmPack;
997330f729Sjoerg }
1007330f729Sjoerg
getAsTemplateDecl() const1017330f729Sjoerg TemplateDecl *TemplateName::getAsTemplateDecl() const {
1027330f729Sjoerg if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
1037330f729Sjoerg return Template;
1047330f729Sjoerg
1057330f729Sjoerg if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
1067330f729Sjoerg return QTN->getTemplateDecl();
1077330f729Sjoerg
1087330f729Sjoerg if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
1097330f729Sjoerg return sub->getReplacement().getAsTemplateDecl();
1107330f729Sjoerg
1117330f729Sjoerg return nullptr;
1127330f729Sjoerg }
1137330f729Sjoerg
getAsOverloadedTemplate() const1147330f729Sjoerg OverloadedTemplateStorage *TemplateName::getAsOverloadedTemplate() const {
1157330f729Sjoerg if (UncommonTemplateNameStorage *Uncommon =
1167330f729Sjoerg Storage.dyn_cast<UncommonTemplateNameStorage *>())
1177330f729Sjoerg return Uncommon->getAsOverloadedStorage();
1187330f729Sjoerg
1197330f729Sjoerg return nullptr;
1207330f729Sjoerg }
1217330f729Sjoerg
getAsAssumedTemplateName() const1227330f729Sjoerg AssumedTemplateStorage *TemplateName::getAsAssumedTemplateName() const {
1237330f729Sjoerg if (UncommonTemplateNameStorage *Uncommon =
1247330f729Sjoerg Storage.dyn_cast<UncommonTemplateNameStorage *>())
1257330f729Sjoerg return Uncommon->getAsAssumedTemplateName();
1267330f729Sjoerg
1277330f729Sjoerg return nullptr;
1287330f729Sjoerg }
1297330f729Sjoerg
1307330f729Sjoerg SubstTemplateTemplateParmStorage *
getAsSubstTemplateTemplateParm() const1317330f729Sjoerg TemplateName::getAsSubstTemplateTemplateParm() const {
1327330f729Sjoerg if (UncommonTemplateNameStorage *uncommon =
1337330f729Sjoerg Storage.dyn_cast<UncommonTemplateNameStorage *>())
1347330f729Sjoerg return uncommon->getAsSubstTemplateTemplateParm();
1357330f729Sjoerg
1367330f729Sjoerg return nullptr;
1377330f729Sjoerg }
1387330f729Sjoerg
1397330f729Sjoerg SubstTemplateTemplateParmPackStorage *
getAsSubstTemplateTemplateParmPack() const1407330f729Sjoerg TemplateName::getAsSubstTemplateTemplateParmPack() const {
1417330f729Sjoerg if (UncommonTemplateNameStorage *Uncommon =
1427330f729Sjoerg Storage.dyn_cast<UncommonTemplateNameStorage *>())
1437330f729Sjoerg return Uncommon->getAsSubstTemplateTemplateParmPack();
1447330f729Sjoerg
1457330f729Sjoerg return nullptr;
1467330f729Sjoerg }
1477330f729Sjoerg
getAsQualifiedTemplateName() const1487330f729Sjoerg QualifiedTemplateName *TemplateName::getAsQualifiedTemplateName() const {
1497330f729Sjoerg return Storage.dyn_cast<QualifiedTemplateName *>();
1507330f729Sjoerg }
1517330f729Sjoerg
getAsDependentTemplateName() const1527330f729Sjoerg DependentTemplateName *TemplateName::getAsDependentTemplateName() const {
1537330f729Sjoerg return Storage.dyn_cast<DependentTemplateName *>();
1547330f729Sjoerg }
1557330f729Sjoerg
getNameToSubstitute() const1567330f729Sjoerg TemplateName TemplateName::getNameToSubstitute() const {
1577330f729Sjoerg TemplateDecl *Decl = getAsTemplateDecl();
1587330f729Sjoerg
1597330f729Sjoerg // Substituting a dependent template name: preserve it as written.
1607330f729Sjoerg if (!Decl)
1617330f729Sjoerg return *this;
1627330f729Sjoerg
1637330f729Sjoerg // If we have a template declaration, use the most recent non-friend
1647330f729Sjoerg // declaration of that template.
1657330f729Sjoerg Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
1667330f729Sjoerg while (Decl->getFriendObjectKind()) {
1677330f729Sjoerg Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
1687330f729Sjoerg assert(Decl && "all declarations of template are friends");
1697330f729Sjoerg }
1707330f729Sjoerg return TemplateName(Decl);
1717330f729Sjoerg }
1727330f729Sjoerg
getDependence() const173*e038c9c4Sjoerg TemplateNameDependence TemplateName::getDependence() const {
174*e038c9c4Sjoerg auto D = TemplateNameDependence::None;
175*e038c9c4Sjoerg switch (getKind()) {
176*e038c9c4Sjoerg case TemplateName::NameKind::QualifiedTemplate:
177*e038c9c4Sjoerg D |= toTemplateNameDependence(
178*e038c9c4Sjoerg getAsQualifiedTemplateName()->getQualifier()->getDependence());
179*e038c9c4Sjoerg break;
180*e038c9c4Sjoerg case TemplateName::NameKind::DependentTemplate:
181*e038c9c4Sjoerg D |= toTemplateNameDependence(
182*e038c9c4Sjoerg getAsDependentTemplateName()->getQualifier()->getDependence());
183*e038c9c4Sjoerg break;
184*e038c9c4Sjoerg case TemplateName::NameKind::SubstTemplateTemplateParmPack:
185*e038c9c4Sjoerg D |= TemplateNameDependence::UnexpandedPack;
186*e038c9c4Sjoerg break;
187*e038c9c4Sjoerg case TemplateName::NameKind::OverloadedTemplate:
188*e038c9c4Sjoerg llvm_unreachable("overloaded templates shouldn't survive to here.");
189*e038c9c4Sjoerg default:
190*e038c9c4Sjoerg break;
191*e038c9c4Sjoerg }
1927330f729Sjoerg if (TemplateDecl *Template = getAsTemplateDecl()) {
193*e038c9c4Sjoerg if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) {
194*e038c9c4Sjoerg D |= TemplateNameDependence::DependentInstantiation;
195*e038c9c4Sjoerg if (TTP->isParameterPack())
196*e038c9c4Sjoerg D |= TemplateNameDependence::UnexpandedPack;
197*e038c9c4Sjoerg }
1987330f729Sjoerg // FIXME: Hack, getDeclContext() can be null if Template is still
1997330f729Sjoerg // initializing due to PCH reading, so we check it before using it.
2007330f729Sjoerg // Should probably modify TemplateSpecializationType to allow constructing
2017330f729Sjoerg // it without the isDependent() checking.
202*e038c9c4Sjoerg if (Template->getDeclContext() &&
203*e038c9c4Sjoerg Template->getDeclContext()->isDependentContext())
204*e038c9c4Sjoerg D |= TemplateNameDependence::DependentInstantiation;
205*e038c9c4Sjoerg } else {
206*e038c9c4Sjoerg D |= TemplateNameDependence::DependentInstantiation;
207*e038c9c4Sjoerg }
208*e038c9c4Sjoerg return D;
2097330f729Sjoerg }
2107330f729Sjoerg
isDependent() const211*e038c9c4Sjoerg bool TemplateName::isDependent() const {
212*e038c9c4Sjoerg return getDependence() & TemplateNameDependence::Dependent;
2137330f729Sjoerg }
2147330f729Sjoerg
isInstantiationDependent() const2157330f729Sjoerg bool TemplateName::isInstantiationDependent() const {
216*e038c9c4Sjoerg return getDependence() & TemplateNameDependence::Instantiation;
2177330f729Sjoerg }
2187330f729Sjoerg
containsUnexpandedParameterPack() const2197330f729Sjoerg bool TemplateName::containsUnexpandedParameterPack() const {
220*e038c9c4Sjoerg return getDependence() & TemplateNameDependence::UnexpandedPack;
2217330f729Sjoerg }
2227330f729Sjoerg
2237330f729Sjoerg void
print(raw_ostream & OS,const PrintingPolicy & Policy,bool SuppressNNS) const2247330f729Sjoerg TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
2257330f729Sjoerg bool SuppressNNS) const {
2267330f729Sjoerg if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
2277330f729Sjoerg OS << *Template;
2287330f729Sjoerg else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
2297330f729Sjoerg if (!SuppressNNS)
2307330f729Sjoerg QTN->getQualifier()->print(OS, Policy);
2317330f729Sjoerg if (QTN->hasTemplateKeyword())
2327330f729Sjoerg OS << "template ";
2337330f729Sjoerg OS << *QTN->getDecl();
2347330f729Sjoerg } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
2357330f729Sjoerg if (!SuppressNNS && DTN->getQualifier())
2367330f729Sjoerg DTN->getQualifier()->print(OS, Policy);
2377330f729Sjoerg OS << "template ";
2387330f729Sjoerg
2397330f729Sjoerg if (DTN->isIdentifier())
2407330f729Sjoerg OS << DTN->getIdentifier()->getName();
2417330f729Sjoerg else
2427330f729Sjoerg OS << "operator " << getOperatorSpelling(DTN->getOperator());
2437330f729Sjoerg } else if (SubstTemplateTemplateParmStorage *subst
2447330f729Sjoerg = getAsSubstTemplateTemplateParm()) {
2457330f729Sjoerg subst->getReplacement().print(OS, Policy, SuppressNNS);
2467330f729Sjoerg } else if (SubstTemplateTemplateParmPackStorage *SubstPack
2477330f729Sjoerg = getAsSubstTemplateTemplateParmPack())
2487330f729Sjoerg OS << *SubstPack->getParameterPack();
2497330f729Sjoerg else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
2507330f729Sjoerg Assumed->getDeclName().print(OS, Policy);
2517330f729Sjoerg } else {
2527330f729Sjoerg OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
2537330f729Sjoerg (*OTS->begin())->printName(OS);
2547330f729Sjoerg }
2557330f729Sjoerg }
2567330f729Sjoerg
operator <<(const StreamingDiagnostic & DB,TemplateName N)257*e038c9c4Sjoerg const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
2587330f729Sjoerg TemplateName N) {
2597330f729Sjoerg std::string NameStr;
2607330f729Sjoerg llvm::raw_string_ostream OS(NameStr);
2617330f729Sjoerg LangOptions LO;
2627330f729Sjoerg LO.CPlusPlus = true;
2637330f729Sjoerg LO.Bool = true;
2647330f729Sjoerg OS << '\'';
2657330f729Sjoerg N.print(OS, PrintingPolicy(LO));
2667330f729Sjoerg OS << '\'';
2677330f729Sjoerg OS.flush();
2687330f729Sjoerg return DB << NameStr;
2697330f729Sjoerg }
2707330f729Sjoerg
dump(raw_ostream & OS) const2717330f729Sjoerg void TemplateName::dump(raw_ostream &OS) const {
2727330f729Sjoerg LangOptions LO; // FIXME!
2737330f729Sjoerg LO.CPlusPlus = true;
2747330f729Sjoerg LO.Bool = true;
2757330f729Sjoerg print(OS, PrintingPolicy(LO));
2767330f729Sjoerg }
2777330f729Sjoerg
dump() const2787330f729Sjoerg LLVM_DUMP_METHOD void TemplateName::dump() const {
2797330f729Sjoerg dump(llvm::errs());
2807330f729Sjoerg }
281