xref: /openbsd-src/gnu/llvm/clang/lib/AST/TemplateName.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===- TemplateName.cpp - C++ Template Name Representation ----------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick //  This file defines the TemplateName interface and subclasses.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #include "clang/AST/TemplateName.h"
14ec727ea7Spatrick #include "clang/AST/Decl.h"
15e5dd7070Spatrick #include "clang/AST/DeclBase.h"
16*12c85518Srobert #include "clang/AST/DeclCXX.h"
17e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
18ec727ea7Spatrick #include "clang/AST/DependenceFlags.h"
19e5dd7070Spatrick #include "clang/AST/NestedNameSpecifier.h"
20e5dd7070Spatrick #include "clang/AST/PrettyPrinter.h"
21e5dd7070Spatrick #include "clang/AST/TemplateBase.h"
22e5dd7070Spatrick #include "clang/Basic/Diagnostic.h"
23e5dd7070Spatrick #include "clang/Basic/LLVM.h"
24e5dd7070Spatrick #include "clang/Basic/LangOptions.h"
25e5dd7070Spatrick #include "clang/Basic/OperatorKinds.h"
26e5dd7070Spatrick #include "llvm/ADT/ArrayRef.h"
27e5dd7070Spatrick #include "llvm/ADT/FoldingSet.h"
28e5dd7070Spatrick #include "llvm/Support/Casting.h"
29e5dd7070Spatrick #include "llvm/Support/Compiler.h"
30e5dd7070Spatrick #include "llvm/Support/raw_ostream.h"
31e5dd7070Spatrick #include <cassert>
32*12c85518Srobert #include <optional>
33e5dd7070Spatrick #include <string>
34e5dd7070Spatrick 
35e5dd7070Spatrick using namespace clang;
36e5dd7070Spatrick 
37e5dd7070Spatrick TemplateArgument
getArgumentPack() const38e5dd7070Spatrick SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
39*12c85518Srobert   return TemplateArgument(llvm::ArrayRef(Arguments, Bits.Data));
40*12c85518Srobert }
41*12c85518Srobert 
42*12c85518Srobert TemplateTemplateParmDecl *
getParameterPack() const43*12c85518Srobert SubstTemplateTemplateParmPackStorage::getParameterPack() const {
44*12c85518Srobert   return cast<TemplateTemplateParmDecl>(
45*12c85518Srobert       getReplacedTemplateParameterList(getAssociatedDecl())
46*12c85518Srobert           ->asArray()[Bits.Index]);
47*12c85518Srobert }
48*12c85518Srobert 
49*12c85518Srobert TemplateTemplateParmDecl *
getParameter() const50*12c85518Srobert SubstTemplateTemplateParmStorage::getParameter() const {
51*12c85518Srobert   return cast<TemplateTemplateParmDecl>(
52*12c85518Srobert       getReplacedTemplateParameterList(getAssociatedDecl())
53*12c85518Srobert           ->asArray()[Bits.Index]);
54e5dd7070Spatrick }
55e5dd7070Spatrick 
Profile(llvm::FoldingSetNodeID & ID)56e5dd7070Spatrick void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
57*12c85518Srobert   Profile(ID, Replacement, getAssociatedDecl(), getIndex(), getPackIndex());
58e5dd7070Spatrick }
59e5dd7070Spatrick 
Profile(llvm::FoldingSetNodeID & ID,TemplateName Replacement,Decl * AssociatedDecl,unsigned Index,std::optional<unsigned> PackIndex)60*12c85518Srobert void SubstTemplateTemplateParmStorage::Profile(
61*12c85518Srobert     llvm::FoldingSetNodeID &ID, TemplateName Replacement, Decl *AssociatedDecl,
62*12c85518Srobert     unsigned Index, std::optional<unsigned> PackIndex) {
63*12c85518Srobert   Replacement.Profile(ID);
64*12c85518Srobert   ID.AddPointer(AssociatedDecl);
65*12c85518Srobert   ID.AddInteger(Index);
66*12c85518Srobert   ID.AddInteger(PackIndex ? *PackIndex + 1 : 0);
67*12c85518Srobert }
68*12c85518Srobert 
SubstTemplateTemplateParmPackStorage(ArrayRef<TemplateArgument> ArgPack,Decl * AssociatedDecl,unsigned Index,bool Final)69*12c85518Srobert SubstTemplateTemplateParmPackStorage::SubstTemplateTemplateParmPackStorage(
70*12c85518Srobert     ArrayRef<TemplateArgument> ArgPack, Decl *AssociatedDecl, unsigned Index,
71*12c85518Srobert     bool Final)
72*12c85518Srobert     : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Index,
73*12c85518Srobert                                   ArgPack.size()),
74*12c85518Srobert       Arguments(ArgPack.data()), AssociatedDeclAndFinal(AssociatedDecl, Final) {
75*12c85518Srobert   assert(AssociatedDecl != nullptr);
76e5dd7070Spatrick }
77e5dd7070Spatrick 
Profile(llvm::FoldingSetNodeID & ID,ASTContext & Context)78e5dd7070Spatrick void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
79e5dd7070Spatrick                                                    ASTContext &Context) {
80*12c85518Srobert   Profile(ID, Context, getArgumentPack(), getAssociatedDecl(), getIndex(),
81*12c85518Srobert           getFinal());
82e5dd7070Spatrick }
83e5dd7070Spatrick 
getAssociatedDecl() const84*12c85518Srobert Decl *SubstTemplateTemplateParmPackStorage::getAssociatedDecl() const {
85*12c85518Srobert   return AssociatedDeclAndFinal.getPointer();
86*12c85518Srobert }
87*12c85518Srobert 
getFinal() const88*12c85518Srobert bool SubstTemplateTemplateParmPackStorage::getFinal() const {
89*12c85518Srobert   return AssociatedDeclAndFinal.getInt();
90*12c85518Srobert }
91*12c85518Srobert 
Profile(llvm::FoldingSetNodeID & ID,ASTContext & Context,const TemplateArgument & ArgPack,Decl * AssociatedDecl,unsigned Index,bool Final)92*12c85518Srobert void SubstTemplateTemplateParmPackStorage::Profile(
93*12c85518Srobert     llvm::FoldingSetNodeID &ID, ASTContext &Context,
94*12c85518Srobert     const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index,
95*12c85518Srobert     bool Final) {
96e5dd7070Spatrick   ArgPack.Profile(ID, Context);
97*12c85518Srobert   ID.AddPointer(AssociatedDecl);
98*12c85518Srobert   ID.AddInteger(Index);
99*12c85518Srobert   ID.AddBoolean(Final);
100e5dd7070Spatrick }
101e5dd7070Spatrick 
TemplateName(void * Ptr)102e5dd7070Spatrick TemplateName::TemplateName(void *Ptr) {
103e5dd7070Spatrick   Storage = StorageType::getFromOpaqueValue(Ptr);
104e5dd7070Spatrick }
105e5dd7070Spatrick 
TemplateName(TemplateDecl * Template)106e5dd7070Spatrick TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
TemplateName(OverloadedTemplateStorage * Storage)107e5dd7070Spatrick TemplateName::TemplateName(OverloadedTemplateStorage *Storage)
108e5dd7070Spatrick     : Storage(Storage) {}
TemplateName(AssumedTemplateStorage * Storage)109e5dd7070Spatrick TemplateName::TemplateName(AssumedTemplateStorage *Storage)
110e5dd7070Spatrick     : Storage(Storage) {}
TemplateName(SubstTemplateTemplateParmStorage * Storage)111e5dd7070Spatrick TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
112e5dd7070Spatrick     : Storage(Storage) {}
TemplateName(SubstTemplateTemplateParmPackStorage * Storage)113e5dd7070Spatrick TemplateName::TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
114e5dd7070Spatrick     : Storage(Storage) {}
TemplateName(QualifiedTemplateName * Qual)115e5dd7070Spatrick TemplateName::TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) {}
TemplateName(DependentTemplateName * Dep)116e5dd7070Spatrick TemplateName::TemplateName(DependentTemplateName *Dep) : Storage(Dep) {}
TemplateName(UsingShadowDecl * Using)117*12c85518Srobert TemplateName::TemplateName(UsingShadowDecl *Using) : Storage(Using) {}
118e5dd7070Spatrick 
isNull() const119e5dd7070Spatrick bool TemplateName::isNull() const { return Storage.isNull(); }
120e5dd7070Spatrick 
getKind() const121e5dd7070Spatrick TemplateName::NameKind TemplateName::getKind() const {
122*12c85518Srobert   if (auto *ND = Storage.dyn_cast<Decl *>()) {
123*12c85518Srobert     if (isa<UsingShadowDecl>(ND))
124*12c85518Srobert       return UsingTemplate;
125*12c85518Srobert     assert(isa<TemplateDecl>(ND));
126e5dd7070Spatrick     return Template;
127*12c85518Srobert   }
128*12c85518Srobert 
129e5dd7070Spatrick   if (Storage.is<DependentTemplateName *>())
130e5dd7070Spatrick     return DependentTemplate;
131e5dd7070Spatrick   if (Storage.is<QualifiedTemplateName *>())
132e5dd7070Spatrick     return QualifiedTemplate;
133e5dd7070Spatrick 
134e5dd7070Spatrick   UncommonTemplateNameStorage *uncommon
135e5dd7070Spatrick     = Storage.get<UncommonTemplateNameStorage*>();
136e5dd7070Spatrick   if (uncommon->getAsOverloadedStorage())
137e5dd7070Spatrick     return OverloadedTemplate;
138e5dd7070Spatrick   if (uncommon->getAsAssumedTemplateName())
139e5dd7070Spatrick     return AssumedTemplate;
140e5dd7070Spatrick   if (uncommon->getAsSubstTemplateTemplateParm())
141e5dd7070Spatrick     return SubstTemplateTemplateParm;
142e5dd7070Spatrick   return SubstTemplateTemplateParmPack;
143e5dd7070Spatrick }
144e5dd7070Spatrick 
getAsTemplateDecl() const145e5dd7070Spatrick TemplateDecl *TemplateName::getAsTemplateDecl() const {
146*12c85518Srobert   if (Decl *TemplateOrUsing = Storage.dyn_cast<Decl *>()) {
147*12c85518Srobert     if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(TemplateOrUsing))
148*12c85518Srobert       return cast<TemplateDecl>(USD->getTargetDecl());
149*12c85518Srobert 
150*12c85518Srobert     assert(isa<TemplateDecl>(TemplateOrUsing));
151*12c85518Srobert     return cast<TemplateDecl>(TemplateOrUsing);
152*12c85518Srobert   }
153e5dd7070Spatrick 
154e5dd7070Spatrick   if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
155*12c85518Srobert     return QTN->getUnderlyingTemplate().getAsTemplateDecl();
156e5dd7070Spatrick 
157e5dd7070Spatrick   if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
158e5dd7070Spatrick     return sub->getReplacement().getAsTemplateDecl();
159e5dd7070Spatrick 
160*12c85518Srobert   if (UsingShadowDecl *USD = getAsUsingShadowDecl())
161*12c85518Srobert     return cast<TemplateDecl>(USD->getTargetDecl());
162*12c85518Srobert 
163e5dd7070Spatrick   return nullptr;
164e5dd7070Spatrick }
165e5dd7070Spatrick 
getAsOverloadedTemplate() const166e5dd7070Spatrick OverloadedTemplateStorage *TemplateName::getAsOverloadedTemplate() const {
167e5dd7070Spatrick   if (UncommonTemplateNameStorage *Uncommon =
168e5dd7070Spatrick           Storage.dyn_cast<UncommonTemplateNameStorage *>())
169e5dd7070Spatrick     return Uncommon->getAsOverloadedStorage();
170e5dd7070Spatrick 
171e5dd7070Spatrick   return nullptr;
172e5dd7070Spatrick }
173e5dd7070Spatrick 
getAsAssumedTemplateName() const174e5dd7070Spatrick AssumedTemplateStorage *TemplateName::getAsAssumedTemplateName() const {
175e5dd7070Spatrick   if (UncommonTemplateNameStorage *Uncommon =
176e5dd7070Spatrick           Storage.dyn_cast<UncommonTemplateNameStorage *>())
177e5dd7070Spatrick     return Uncommon->getAsAssumedTemplateName();
178e5dd7070Spatrick 
179e5dd7070Spatrick   return nullptr;
180e5dd7070Spatrick }
181e5dd7070Spatrick 
182e5dd7070Spatrick SubstTemplateTemplateParmStorage *
getAsSubstTemplateTemplateParm() const183e5dd7070Spatrick TemplateName::getAsSubstTemplateTemplateParm() const {
184e5dd7070Spatrick   if (UncommonTemplateNameStorage *uncommon =
185e5dd7070Spatrick           Storage.dyn_cast<UncommonTemplateNameStorage *>())
186e5dd7070Spatrick     return uncommon->getAsSubstTemplateTemplateParm();
187e5dd7070Spatrick 
188e5dd7070Spatrick   return nullptr;
189e5dd7070Spatrick }
190e5dd7070Spatrick 
191e5dd7070Spatrick SubstTemplateTemplateParmPackStorage *
getAsSubstTemplateTemplateParmPack() const192e5dd7070Spatrick TemplateName::getAsSubstTemplateTemplateParmPack() const {
193e5dd7070Spatrick   if (UncommonTemplateNameStorage *Uncommon =
194e5dd7070Spatrick           Storage.dyn_cast<UncommonTemplateNameStorage *>())
195e5dd7070Spatrick     return Uncommon->getAsSubstTemplateTemplateParmPack();
196e5dd7070Spatrick 
197e5dd7070Spatrick   return nullptr;
198e5dd7070Spatrick }
199e5dd7070Spatrick 
getAsQualifiedTemplateName() const200e5dd7070Spatrick QualifiedTemplateName *TemplateName::getAsQualifiedTemplateName() const {
201e5dd7070Spatrick   return Storage.dyn_cast<QualifiedTemplateName *>();
202e5dd7070Spatrick }
203e5dd7070Spatrick 
getAsDependentTemplateName() const204e5dd7070Spatrick DependentTemplateName *TemplateName::getAsDependentTemplateName() const {
205e5dd7070Spatrick   return Storage.dyn_cast<DependentTemplateName *>();
206e5dd7070Spatrick }
207e5dd7070Spatrick 
getAsUsingShadowDecl() const208*12c85518Srobert UsingShadowDecl *TemplateName::getAsUsingShadowDecl() const {
209*12c85518Srobert   if (Decl *D = Storage.dyn_cast<Decl *>())
210*12c85518Srobert     if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D))
211*12c85518Srobert       return USD;
212*12c85518Srobert   if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
213*12c85518Srobert     return QTN->getUnderlyingTemplate().getAsUsingShadowDecl();
214*12c85518Srobert   return nullptr;
215*12c85518Srobert }
216*12c85518Srobert 
getNameToSubstitute() const217e5dd7070Spatrick TemplateName TemplateName::getNameToSubstitute() const {
218e5dd7070Spatrick   TemplateDecl *Decl = getAsTemplateDecl();
219e5dd7070Spatrick 
220e5dd7070Spatrick   // Substituting a dependent template name: preserve it as written.
221e5dd7070Spatrick   if (!Decl)
222e5dd7070Spatrick     return *this;
223e5dd7070Spatrick 
224e5dd7070Spatrick   // If we have a template declaration, use the most recent non-friend
225e5dd7070Spatrick   // declaration of that template.
226e5dd7070Spatrick   Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
227e5dd7070Spatrick   while (Decl->getFriendObjectKind()) {
228e5dd7070Spatrick     Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
229e5dd7070Spatrick     assert(Decl && "all declarations of template are friends");
230e5dd7070Spatrick   }
231e5dd7070Spatrick   return TemplateName(Decl);
232e5dd7070Spatrick }
233e5dd7070Spatrick 
getDependence() const234ec727ea7Spatrick TemplateNameDependence TemplateName::getDependence() const {
235ec727ea7Spatrick   auto D = TemplateNameDependence::None;
236ec727ea7Spatrick   switch (getKind()) {
237ec727ea7Spatrick   case TemplateName::NameKind::QualifiedTemplate:
238ec727ea7Spatrick     D |= toTemplateNameDependence(
239ec727ea7Spatrick         getAsQualifiedTemplateName()->getQualifier()->getDependence());
240ec727ea7Spatrick     break;
241ec727ea7Spatrick   case TemplateName::NameKind::DependentTemplate:
242ec727ea7Spatrick     D |= toTemplateNameDependence(
243ec727ea7Spatrick         getAsDependentTemplateName()->getQualifier()->getDependence());
244ec727ea7Spatrick     break;
245ec727ea7Spatrick   case TemplateName::NameKind::SubstTemplateTemplateParmPack:
246ec727ea7Spatrick     D |= TemplateNameDependence::UnexpandedPack;
247ec727ea7Spatrick     break;
248ec727ea7Spatrick   case TemplateName::NameKind::OverloadedTemplate:
249ec727ea7Spatrick     llvm_unreachable("overloaded templates shouldn't survive to here.");
250ec727ea7Spatrick   default:
251ec727ea7Spatrick     break;
252ec727ea7Spatrick   }
253e5dd7070Spatrick   if (TemplateDecl *Template = getAsTemplateDecl()) {
254ec727ea7Spatrick     if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) {
255ec727ea7Spatrick       D |= TemplateNameDependence::DependentInstantiation;
256ec727ea7Spatrick       if (TTP->isParameterPack())
257ec727ea7Spatrick         D |= TemplateNameDependence::UnexpandedPack;
258ec727ea7Spatrick     }
259e5dd7070Spatrick     // FIXME: Hack, getDeclContext() can be null if Template is still
260e5dd7070Spatrick     // initializing due to PCH reading, so we check it before using it.
261e5dd7070Spatrick     // Should probably modify TemplateSpecializationType to allow constructing
262e5dd7070Spatrick     // it without the isDependent() checking.
263ec727ea7Spatrick     if (Template->getDeclContext() &&
264ec727ea7Spatrick         Template->getDeclContext()->isDependentContext())
265ec727ea7Spatrick       D |= TemplateNameDependence::DependentInstantiation;
266ec727ea7Spatrick   } else {
267ec727ea7Spatrick     D |= TemplateNameDependence::DependentInstantiation;
268ec727ea7Spatrick   }
269ec727ea7Spatrick   return D;
270e5dd7070Spatrick }
271e5dd7070Spatrick 
isDependent() const272ec727ea7Spatrick bool TemplateName::isDependent() const {
273ec727ea7Spatrick   return getDependence() & TemplateNameDependence::Dependent;
274e5dd7070Spatrick }
275e5dd7070Spatrick 
isInstantiationDependent() const276e5dd7070Spatrick bool TemplateName::isInstantiationDependent() const {
277ec727ea7Spatrick   return getDependence() & TemplateNameDependence::Instantiation;
278e5dd7070Spatrick }
279e5dd7070Spatrick 
containsUnexpandedParameterPack() const280e5dd7070Spatrick bool TemplateName::containsUnexpandedParameterPack() const {
281ec727ea7Spatrick   return getDependence() & TemplateNameDependence::UnexpandedPack;
282e5dd7070Spatrick }
283e5dd7070Spatrick 
print(raw_ostream & OS,const PrintingPolicy & Policy,Qualified Qual) const284*12c85518Srobert void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
285*12c85518Srobert                          Qualified Qual) const {
286*12c85518Srobert   auto Kind = getKind();
287*12c85518Srobert   TemplateDecl *Template = nullptr;
288*12c85518Srobert   if (Kind == TemplateName::Template || Kind == TemplateName::UsingTemplate) {
289*12c85518Srobert     // After `namespace ns { using std::vector }`, what is the fully-qualified
290*12c85518Srobert     // name of the UsingTemplateName `vector` within ns?
291*12c85518Srobert     //
292*12c85518Srobert     // - ns::vector (the qualified name of the using-shadow decl)
293*12c85518Srobert     // - std::vector (the qualified name of the underlying template decl)
294*12c85518Srobert     //
295*12c85518Srobert     // Similar to the UsingType behavior, using declarations are used to import
296*12c85518Srobert     // names more often than to export them, thus using the original name is
297*12c85518Srobert     // most useful in this case.
298*12c85518Srobert     Template = getAsTemplateDecl();
299*12c85518Srobert   }
300*12c85518Srobert 
301*12c85518Srobert   if (Template)
302*12c85518Srobert     if (Policy.CleanUglifiedParameters &&
303*12c85518Srobert         isa<TemplateTemplateParmDecl>(Template) && Template->getIdentifier())
304*12c85518Srobert       OS << Template->getIdentifier()->deuglifiedName();
305*12c85518Srobert     else if (Qual == Qualified::Fully &&
306*12c85518Srobert              getDependence() !=
307*12c85518Srobert                  TemplateNameDependenceScope::DependentInstantiation)
308*12c85518Srobert       Template->printQualifiedName(OS, Policy);
309*12c85518Srobert     else
310e5dd7070Spatrick       OS << *Template;
311e5dd7070Spatrick   else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
312*12c85518Srobert     if (Qual == Qualified::Fully &&
313*12c85518Srobert         getDependence() !=
314*12c85518Srobert             TemplateNameDependenceScope::DependentInstantiation) {
315*12c85518Srobert       QTN->getUnderlyingTemplate().getAsTemplateDecl()->printQualifiedName(
316*12c85518Srobert           OS, Policy);
317*12c85518Srobert       return;
318*12c85518Srobert     }
319*12c85518Srobert     if (Qual == Qualified::AsWritten)
320e5dd7070Spatrick       QTN->getQualifier()->print(OS, Policy);
321e5dd7070Spatrick     if (QTN->hasTemplateKeyword())
322e5dd7070Spatrick       OS << "template ";
323*12c85518Srobert     OS << *QTN->getUnderlyingTemplate().getAsTemplateDecl();
324e5dd7070Spatrick   } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
325*12c85518Srobert     if (Qual == Qualified::AsWritten && DTN->getQualifier())
326e5dd7070Spatrick       DTN->getQualifier()->print(OS, Policy);
327e5dd7070Spatrick     OS << "template ";
328e5dd7070Spatrick 
329e5dd7070Spatrick     if (DTN->isIdentifier())
330e5dd7070Spatrick       OS << DTN->getIdentifier()->getName();
331e5dd7070Spatrick     else
332e5dd7070Spatrick       OS << "operator " << getOperatorSpelling(DTN->getOperator());
333e5dd7070Spatrick   } else if (SubstTemplateTemplateParmStorage *subst
334e5dd7070Spatrick                = getAsSubstTemplateTemplateParm()) {
335*12c85518Srobert     subst->getReplacement().print(OS, Policy, Qual);
336e5dd7070Spatrick   } else if (SubstTemplateTemplateParmPackStorage *SubstPack
337e5dd7070Spatrick                                         = getAsSubstTemplateTemplateParmPack())
338e5dd7070Spatrick     OS << *SubstPack->getParameterPack();
339e5dd7070Spatrick   else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
340e5dd7070Spatrick     Assumed->getDeclName().print(OS, Policy);
341e5dd7070Spatrick   } else {
342*12c85518Srobert     assert(getKind() == TemplateName::OverloadedTemplate);
343e5dd7070Spatrick     OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
344*12c85518Srobert     (*OTS->begin())->printName(OS, Policy);
345e5dd7070Spatrick   }
346e5dd7070Spatrick }
347e5dd7070Spatrick 
operator <<(const StreamingDiagnostic & DB,TemplateName N)348a9ac8606Spatrick const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
349e5dd7070Spatrick                                              TemplateName N) {
350e5dd7070Spatrick   std::string NameStr;
351e5dd7070Spatrick   llvm::raw_string_ostream OS(NameStr);
352e5dd7070Spatrick   LangOptions LO;
353e5dd7070Spatrick   LO.CPlusPlus = true;
354e5dd7070Spatrick   LO.Bool = true;
355e5dd7070Spatrick   OS << '\'';
356e5dd7070Spatrick   N.print(OS, PrintingPolicy(LO));
357e5dd7070Spatrick   OS << '\'';
358e5dd7070Spatrick   OS.flush();
359e5dd7070Spatrick   return DB << NameStr;
360e5dd7070Spatrick }
361e5dd7070Spatrick 
dump(raw_ostream & OS) const362e5dd7070Spatrick void TemplateName::dump(raw_ostream &OS) const {
363e5dd7070Spatrick   LangOptions LO;  // FIXME!
364e5dd7070Spatrick   LO.CPlusPlus = true;
365e5dd7070Spatrick   LO.Bool = true;
366e5dd7070Spatrick   print(OS, PrintingPolicy(LO));
367e5dd7070Spatrick }
368e5dd7070Spatrick 
dump() const369e5dd7070Spatrick LLVM_DUMP_METHOD void TemplateName::dump() const {
370e5dd7070Spatrick   dump(llvm::errs());
371e5dd7070Spatrick }
372