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