xref: /aosp_15_r20/external/clang/lib/AST/TemplateName.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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