1 //===- TemplateName.cpp - C++ Template Name Representation ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the TemplateName interface and subclasses.
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/TemplateName.h"
15 #include "clang/AST/DeclBase.h"
16 #include "clang/AST/DeclTemplate.h"
17 #include "clang/AST/NestedNameSpecifier.h"
18 #include "clang/AST/PrettyPrinter.h"
19 #include "clang/AST/TemplateBase.h"
20 #include "clang/Basic/Diagnostic.h"
21 #include "clang/Basic/LLVM.h"
22 #include "clang/Basic/LangOptions.h"
23 #include "clang/Basic/OperatorKinds.h"
24 #include "llvm/ADT/ArrayRef.h"
25 #include "llvm/ADT/FoldingSet.h"
26 #include "llvm/Support/Casting.h"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/raw_ostream.h"
32 using namespace clang;
35 SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
36 return TemplateArgument(llvm::makeArrayRef(Arguments, size()));
39 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
40 Profile(ID, Parameter, Replacement);
43 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
44 TemplateTemplateParmDecl *parameter,
45 TemplateName replacement) {
46 ID.AddPointer(parameter);
47 ID.AddPointer(replacement.getAsVoidPointer());
50 void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
51 ASTContext &Context) {
52 Profile(ID, Context, Parameter, getArgumentPack());
55 void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
57 TemplateTemplateParmDecl *Parameter,
58 const TemplateArgument &ArgPack) {
59 ID.AddPointer(Parameter);
60 ArgPack.Profile(ID, Context);
63 TemplateName::TemplateName(void *Ptr) {
64 Storage = StorageType::getFromOpaqueValue(Ptr);
67 TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
68 TemplateName::TemplateName(OverloadedTemplateStorage *Storage)
70 TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
72 TemplateName::TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
74 TemplateName::TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) {}
75 TemplateName::TemplateName(DependentTemplateName *Dep) : Storage(Dep) {}
77 bool TemplateName::isNull() const { return Storage.isNull(); }
79 TemplateName::NameKind TemplateName::getKind() const {
80 if (Storage.is<TemplateDecl *>())
82 if (Storage.is<DependentTemplateName *>())
83 return DependentTemplate;
84 if (Storage.is<QualifiedTemplateName *>())
85 return QualifiedTemplate;
87 UncommonTemplateNameStorage *uncommon
88 = Storage.get<UncommonTemplateNameStorage*>();
89 if (uncommon->getAsOverloadedStorage())
90 return OverloadedTemplate;
91 if (uncommon->getAsSubstTemplateTemplateParm())
92 return SubstTemplateTemplateParm;
93 return SubstTemplateTemplateParmPack;
96 TemplateDecl *TemplateName::getAsTemplateDecl() const {
97 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
100 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
101 return QTN->getTemplateDecl();
103 if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
104 return sub->getReplacement().getAsTemplateDecl();
109 OverloadedTemplateStorage *TemplateName::getAsOverloadedTemplate() const {
110 if (UncommonTemplateNameStorage *Uncommon =
111 Storage.dyn_cast<UncommonTemplateNameStorage *>())
112 return Uncommon->getAsOverloadedStorage();
117 SubstTemplateTemplateParmStorage *
118 TemplateName::getAsSubstTemplateTemplateParm() const {
119 if (UncommonTemplateNameStorage *uncommon =
120 Storage.dyn_cast<UncommonTemplateNameStorage *>())
121 return uncommon->getAsSubstTemplateTemplateParm();
126 SubstTemplateTemplateParmPackStorage *
127 TemplateName::getAsSubstTemplateTemplateParmPack() const {
128 if (UncommonTemplateNameStorage *Uncommon =
129 Storage.dyn_cast<UncommonTemplateNameStorage *>())
130 return Uncommon->getAsSubstTemplateTemplateParmPack();
135 QualifiedTemplateName *TemplateName::getAsQualifiedTemplateName() const {
136 return Storage.dyn_cast<QualifiedTemplateName *>();
139 DependentTemplateName *TemplateName::getAsDependentTemplateName() const {
140 return Storage.dyn_cast<DependentTemplateName *>();
143 TemplateName TemplateName::getNameToSubstitute() const {
144 TemplateDecl *Decl = getAsTemplateDecl();
146 // Substituting a dependent template name: preserve it as written.
150 // If we have a template declaration, use the most recent non-friend
151 // declaration of that template.
152 Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
153 while (Decl->getFriendObjectKind()) {
154 Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
155 assert(Decl && "all declarations of template are friends");
157 return TemplateName(Decl);
160 bool TemplateName::isDependent() const {
161 if (TemplateDecl *Template = getAsTemplateDecl()) {
162 if (isa<TemplateTemplateParmDecl>(Template))
164 // FIXME: Hack, getDeclContext() can be null if Template is still
165 // initializing due to PCH reading, so we check it before using it.
166 // Should probably modify TemplateSpecializationType to allow constructing
167 // it without the isDependent() checking.
168 return Template->getDeclContext() &&
169 Template->getDeclContext()->isDependentContext();
172 assert(!getAsOverloadedTemplate() &&
173 "overloaded templates shouldn't survive to here");
178 bool TemplateName::isInstantiationDependent() const {
179 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
180 if (QTN->getQualifier()->isInstantiationDependent())
184 return isDependent();
187 bool TemplateName::containsUnexpandedParameterPack() const {
188 if (TemplateDecl *Template = getAsTemplateDecl()) {
189 if (TemplateTemplateParmDecl *TTP
190 = dyn_cast<TemplateTemplateParmDecl>(Template))
191 return TTP->isParameterPack();
196 if (DependentTemplateName *DTN = getAsDependentTemplateName())
197 return DTN->getQualifier() &&
198 DTN->getQualifier()->containsUnexpandedParameterPack();
200 return getAsSubstTemplateTemplateParmPack() != nullptr;
204 TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
205 bool SuppressNNS) const {
206 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
208 else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
210 QTN->getQualifier()->print(OS, Policy);
211 if (QTN->hasTemplateKeyword())
213 OS << *QTN->getDecl();
214 } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
215 if (!SuppressNNS && DTN->getQualifier())
216 DTN->getQualifier()->print(OS, Policy);
219 if (DTN->isIdentifier())
220 OS << DTN->getIdentifier()->getName();
222 OS << "operator " << getOperatorSpelling(DTN->getOperator());
223 } else if (SubstTemplateTemplateParmStorage *subst
224 = getAsSubstTemplateTemplateParm()) {
225 subst->getReplacement().print(OS, Policy, SuppressNNS);
226 } else if (SubstTemplateTemplateParmPackStorage *SubstPack
227 = getAsSubstTemplateTemplateParmPack())
228 OS << *SubstPack->getParameterPack();
230 OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
231 (*OTS->begin())->printName(OS);
235 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
238 llvm::raw_string_ostream OS(NameStr);
243 N.print(OS, PrintingPolicy(LO));
246 return DB << NameStr;
249 void TemplateName::dump(raw_ostream &OS) const {
250 LangOptions LO; // FIXME!
253 print(OS, PrintingPolicy(LO));
256 LLVM_DUMP_METHOD void TemplateName::dump() const {