xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/AST/TemplateName.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
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