1*67e74705SXin Li //===--- TemplateName.cpp - C++ Template Name Representation---------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file defines the TemplateName interface and subclasses.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li
14*67e74705SXin Li #include "clang/AST/TemplateName.h"
15*67e74705SXin Li #include "clang/AST/DeclTemplate.h"
16*67e74705SXin Li #include "clang/AST/NestedNameSpecifier.h"
17*67e74705SXin Li #include "clang/AST/PrettyPrinter.h"
18*67e74705SXin Li #include "clang/AST/TemplateBase.h"
19*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
20*67e74705SXin Li #include "clang/Basic/LangOptions.h"
21*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
22*67e74705SXin Li using namespace clang;
23*67e74705SXin Li using namespace llvm;
24*67e74705SXin Li
25*67e74705SXin Li TemplateArgument
getArgumentPack() const26*67e74705SXin Li SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
27*67e74705SXin Li return TemplateArgument(llvm::makeArrayRef(Arguments, size()));
28*67e74705SXin Li }
29*67e74705SXin Li
Profile(llvm::FoldingSetNodeID & ID)30*67e74705SXin Li void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
31*67e74705SXin Li Profile(ID, Parameter, Replacement);
32*67e74705SXin Li }
33*67e74705SXin Li
Profile(llvm::FoldingSetNodeID & ID,TemplateTemplateParmDecl * parameter,TemplateName replacement)34*67e74705SXin Li void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
35*67e74705SXin Li TemplateTemplateParmDecl *parameter,
36*67e74705SXin Li TemplateName replacement) {
37*67e74705SXin Li ID.AddPointer(parameter);
38*67e74705SXin Li ID.AddPointer(replacement.getAsVoidPointer());
39*67e74705SXin Li }
40*67e74705SXin Li
Profile(llvm::FoldingSetNodeID & ID,ASTContext & Context)41*67e74705SXin Li void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
42*67e74705SXin Li ASTContext &Context) {
43*67e74705SXin Li Profile(ID, Context, Parameter, getArgumentPack());
44*67e74705SXin Li }
45*67e74705SXin Li
Profile(llvm::FoldingSetNodeID & ID,ASTContext & Context,TemplateTemplateParmDecl * Parameter,const TemplateArgument & ArgPack)46*67e74705SXin Li void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
47*67e74705SXin Li ASTContext &Context,
48*67e74705SXin Li TemplateTemplateParmDecl *Parameter,
49*67e74705SXin Li const TemplateArgument &ArgPack) {
50*67e74705SXin Li ID.AddPointer(Parameter);
51*67e74705SXin Li ArgPack.Profile(ID, Context);
52*67e74705SXin Li }
53*67e74705SXin Li
TemplateName(void * Ptr)54*67e74705SXin Li TemplateName::TemplateName(void *Ptr) {
55*67e74705SXin Li Storage = StorageType::getFromOpaqueValue(Ptr);
56*67e74705SXin Li }
57*67e74705SXin Li
TemplateName(TemplateDecl * Template)58*67e74705SXin Li TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
TemplateName(OverloadedTemplateStorage * Storage)59*67e74705SXin Li TemplateName::TemplateName(OverloadedTemplateStorage *Storage)
60*67e74705SXin Li : Storage(Storage) {}
TemplateName(SubstTemplateTemplateParmStorage * Storage)61*67e74705SXin Li TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
62*67e74705SXin Li : Storage(Storage) {}
TemplateName(SubstTemplateTemplateParmPackStorage * Storage)63*67e74705SXin Li TemplateName::TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
64*67e74705SXin Li : Storage(Storage) {}
TemplateName(QualifiedTemplateName * Qual)65*67e74705SXin Li TemplateName::TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) {}
TemplateName(DependentTemplateName * Dep)66*67e74705SXin Li TemplateName::TemplateName(DependentTemplateName *Dep) : Storage(Dep) {}
67*67e74705SXin Li
isNull() const68*67e74705SXin Li bool TemplateName::isNull() const { return Storage.isNull(); }
69*67e74705SXin Li
getKind() const70*67e74705SXin Li TemplateName::NameKind TemplateName::getKind() const {
71*67e74705SXin Li if (Storage.is<TemplateDecl *>())
72*67e74705SXin Li return Template;
73*67e74705SXin Li if (Storage.is<DependentTemplateName *>())
74*67e74705SXin Li return DependentTemplate;
75*67e74705SXin Li if (Storage.is<QualifiedTemplateName *>())
76*67e74705SXin Li return QualifiedTemplate;
77*67e74705SXin Li
78*67e74705SXin Li UncommonTemplateNameStorage *uncommon
79*67e74705SXin Li = Storage.get<UncommonTemplateNameStorage*>();
80*67e74705SXin Li if (uncommon->getAsOverloadedStorage())
81*67e74705SXin Li return OverloadedTemplate;
82*67e74705SXin Li if (uncommon->getAsSubstTemplateTemplateParm())
83*67e74705SXin Li return SubstTemplateTemplateParm;
84*67e74705SXin Li return SubstTemplateTemplateParmPack;
85*67e74705SXin Li }
86*67e74705SXin Li
getAsTemplateDecl() const87*67e74705SXin Li TemplateDecl *TemplateName::getAsTemplateDecl() const {
88*67e74705SXin Li if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
89*67e74705SXin Li return Template;
90*67e74705SXin Li
91*67e74705SXin Li if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
92*67e74705SXin Li return QTN->getTemplateDecl();
93*67e74705SXin Li
94*67e74705SXin Li if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
95*67e74705SXin Li return sub->getReplacement().getAsTemplateDecl();
96*67e74705SXin Li
97*67e74705SXin Li return nullptr;
98*67e74705SXin Li }
99*67e74705SXin Li
getAsOverloadedTemplate() const100*67e74705SXin Li OverloadedTemplateStorage *TemplateName::getAsOverloadedTemplate() const {
101*67e74705SXin Li if (UncommonTemplateNameStorage *Uncommon =
102*67e74705SXin Li Storage.dyn_cast<UncommonTemplateNameStorage *>())
103*67e74705SXin Li return Uncommon->getAsOverloadedStorage();
104*67e74705SXin Li
105*67e74705SXin Li return nullptr;
106*67e74705SXin Li }
107*67e74705SXin Li
108*67e74705SXin Li SubstTemplateTemplateParmStorage *
getAsSubstTemplateTemplateParm() const109*67e74705SXin Li TemplateName::getAsSubstTemplateTemplateParm() const {
110*67e74705SXin Li if (UncommonTemplateNameStorage *uncommon =
111*67e74705SXin Li Storage.dyn_cast<UncommonTemplateNameStorage *>())
112*67e74705SXin Li return uncommon->getAsSubstTemplateTemplateParm();
113*67e74705SXin Li
114*67e74705SXin Li return nullptr;
115*67e74705SXin Li }
116*67e74705SXin Li
117*67e74705SXin Li SubstTemplateTemplateParmPackStorage *
getAsSubstTemplateTemplateParmPack() const118*67e74705SXin Li TemplateName::getAsSubstTemplateTemplateParmPack() const {
119*67e74705SXin Li if (UncommonTemplateNameStorage *Uncommon =
120*67e74705SXin Li Storage.dyn_cast<UncommonTemplateNameStorage *>())
121*67e74705SXin Li return Uncommon->getAsSubstTemplateTemplateParmPack();
122*67e74705SXin Li
123*67e74705SXin Li return nullptr;
124*67e74705SXin Li }
125*67e74705SXin Li
getAsQualifiedTemplateName() const126*67e74705SXin Li QualifiedTemplateName *TemplateName::getAsQualifiedTemplateName() const {
127*67e74705SXin Li return Storage.dyn_cast<QualifiedTemplateName *>();
128*67e74705SXin Li }
129*67e74705SXin Li
getAsDependentTemplateName() const130*67e74705SXin Li DependentTemplateName *TemplateName::getAsDependentTemplateName() const {
131*67e74705SXin Li return Storage.dyn_cast<DependentTemplateName *>();
132*67e74705SXin Li }
133*67e74705SXin Li
isDependent() const134*67e74705SXin Li bool TemplateName::isDependent() const {
135*67e74705SXin Li if (TemplateDecl *Template = getAsTemplateDecl()) {
136*67e74705SXin Li if (isa<TemplateTemplateParmDecl>(Template))
137*67e74705SXin Li return true;
138*67e74705SXin Li // FIXME: Hack, getDeclContext() can be null if Template is still
139*67e74705SXin Li // initializing due to PCH reading, so we check it before using it.
140*67e74705SXin Li // Should probably modify TemplateSpecializationType to allow constructing
141*67e74705SXin Li // it without the isDependent() checking.
142*67e74705SXin Li return Template->getDeclContext() &&
143*67e74705SXin Li Template->getDeclContext()->isDependentContext();
144*67e74705SXin Li }
145*67e74705SXin Li
146*67e74705SXin Li assert(!getAsOverloadedTemplate() &&
147*67e74705SXin Li "overloaded templates shouldn't survive to here");
148*67e74705SXin Li
149*67e74705SXin Li return true;
150*67e74705SXin Li }
151*67e74705SXin Li
isInstantiationDependent() const152*67e74705SXin Li bool TemplateName::isInstantiationDependent() const {
153*67e74705SXin Li if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
154*67e74705SXin Li if (QTN->getQualifier()->isInstantiationDependent())
155*67e74705SXin Li return true;
156*67e74705SXin Li }
157*67e74705SXin Li
158*67e74705SXin Li return isDependent();
159*67e74705SXin Li }
160*67e74705SXin Li
containsUnexpandedParameterPack() const161*67e74705SXin Li bool TemplateName::containsUnexpandedParameterPack() const {
162*67e74705SXin Li if (TemplateDecl *Template = getAsTemplateDecl()) {
163*67e74705SXin Li if (TemplateTemplateParmDecl *TTP
164*67e74705SXin Li = dyn_cast<TemplateTemplateParmDecl>(Template))
165*67e74705SXin Li return TTP->isParameterPack();
166*67e74705SXin Li
167*67e74705SXin Li return false;
168*67e74705SXin Li }
169*67e74705SXin Li
170*67e74705SXin Li if (DependentTemplateName *DTN = getAsDependentTemplateName())
171*67e74705SXin Li return DTN->getQualifier() &&
172*67e74705SXin Li DTN->getQualifier()->containsUnexpandedParameterPack();
173*67e74705SXin Li
174*67e74705SXin Li return getAsSubstTemplateTemplateParmPack() != nullptr;
175*67e74705SXin Li }
176*67e74705SXin Li
177*67e74705SXin Li void
print(raw_ostream & OS,const PrintingPolicy & Policy,bool SuppressNNS) const178*67e74705SXin Li TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
179*67e74705SXin Li bool SuppressNNS) const {
180*67e74705SXin Li if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
181*67e74705SXin Li OS << *Template;
182*67e74705SXin Li else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
183*67e74705SXin Li if (!SuppressNNS)
184*67e74705SXin Li QTN->getQualifier()->print(OS, Policy);
185*67e74705SXin Li if (QTN->hasTemplateKeyword())
186*67e74705SXin Li OS << "template ";
187*67e74705SXin Li OS << *QTN->getDecl();
188*67e74705SXin Li } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
189*67e74705SXin Li if (!SuppressNNS && DTN->getQualifier())
190*67e74705SXin Li DTN->getQualifier()->print(OS, Policy);
191*67e74705SXin Li OS << "template ";
192*67e74705SXin Li
193*67e74705SXin Li if (DTN->isIdentifier())
194*67e74705SXin Li OS << DTN->getIdentifier()->getName();
195*67e74705SXin Li else
196*67e74705SXin Li OS << "operator " << getOperatorSpelling(DTN->getOperator());
197*67e74705SXin Li } else if (SubstTemplateTemplateParmStorage *subst
198*67e74705SXin Li = getAsSubstTemplateTemplateParm()) {
199*67e74705SXin Li subst->getReplacement().print(OS, Policy, SuppressNNS);
200*67e74705SXin Li } else if (SubstTemplateTemplateParmPackStorage *SubstPack
201*67e74705SXin Li = getAsSubstTemplateTemplateParmPack())
202*67e74705SXin Li OS << *SubstPack->getParameterPack();
203*67e74705SXin Li else {
204*67e74705SXin Li OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
205*67e74705SXin Li (*OTS->begin())->printName(OS);
206*67e74705SXin Li }
207*67e74705SXin Li }
208*67e74705SXin Li
operator <<(const DiagnosticBuilder & DB,TemplateName N)209*67e74705SXin Li const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
210*67e74705SXin Li TemplateName N) {
211*67e74705SXin Li std::string NameStr;
212*67e74705SXin Li raw_string_ostream OS(NameStr);
213*67e74705SXin Li LangOptions LO;
214*67e74705SXin Li LO.CPlusPlus = true;
215*67e74705SXin Li LO.Bool = true;
216*67e74705SXin Li OS << '\'';
217*67e74705SXin Li N.print(OS, PrintingPolicy(LO));
218*67e74705SXin Li OS << '\'';
219*67e74705SXin Li OS.flush();
220*67e74705SXin Li return DB << NameStr;
221*67e74705SXin Li }
222*67e74705SXin Li
dump(raw_ostream & OS) const223*67e74705SXin Li void TemplateName::dump(raw_ostream &OS) const {
224*67e74705SXin Li LangOptions LO; // FIXME!
225*67e74705SXin Li LO.CPlusPlus = true;
226*67e74705SXin Li LO.Bool = true;
227*67e74705SXin Li print(OS, PrintingPolicy(LO));
228*67e74705SXin Li }
229*67e74705SXin Li
dump() const230*67e74705SXin Li LLVM_DUMP_METHOD void TemplateName::dump() const {
231*67e74705SXin Li dump(llvm::errs());
232*67e74705SXin Li }
233