xref: /minix3/external/bsd/llvm/dist/clang/lib/AST/TemplateName.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- TemplateName.cpp - C++ Template Name Representation---------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file defines the TemplateName interface and subclasses.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "clang/AST/TemplateName.h"
15f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
16f4a2713aSLionel Sambuc #include "clang/AST/NestedNameSpecifier.h"
17f4a2713aSLionel Sambuc #include "clang/AST/PrettyPrinter.h"
18f4a2713aSLionel Sambuc #include "clang/AST/TemplateBase.h"
19f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h"
20f4a2713aSLionel Sambuc #include "clang/Basic/LangOptions.h"
21f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
22f4a2713aSLionel Sambuc using namespace clang;
23f4a2713aSLionel Sambuc using namespace llvm;
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc TemplateArgument
getArgumentPack() const26f4a2713aSLionel Sambuc SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
27f4a2713aSLionel Sambuc   return TemplateArgument(Arguments, size());
28f4a2713aSLionel Sambuc }
29f4a2713aSLionel Sambuc 
Profile(llvm::FoldingSetNodeID & ID)30f4a2713aSLionel Sambuc void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
31f4a2713aSLionel Sambuc   Profile(ID, Parameter, Replacement);
32f4a2713aSLionel Sambuc }
33f4a2713aSLionel Sambuc 
Profile(llvm::FoldingSetNodeID & ID,TemplateTemplateParmDecl * parameter,TemplateName replacement)34f4a2713aSLionel Sambuc void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
35f4a2713aSLionel Sambuc                                            TemplateTemplateParmDecl *parameter,
36f4a2713aSLionel Sambuc                                                TemplateName replacement) {
37f4a2713aSLionel Sambuc   ID.AddPointer(parameter);
38f4a2713aSLionel Sambuc   ID.AddPointer(replacement.getAsVoidPointer());
39f4a2713aSLionel Sambuc }
40f4a2713aSLionel Sambuc 
Profile(llvm::FoldingSetNodeID & ID,ASTContext & Context)41f4a2713aSLionel Sambuc void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
42f4a2713aSLionel Sambuc                                                    ASTContext &Context) {
43f4a2713aSLionel Sambuc   Profile(ID, Context, Parameter, TemplateArgument(Arguments, size()));
44f4a2713aSLionel Sambuc }
45f4a2713aSLionel Sambuc 
Profile(llvm::FoldingSetNodeID & ID,ASTContext & Context,TemplateTemplateParmDecl * Parameter,const TemplateArgument & ArgPack)46f4a2713aSLionel Sambuc void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
47f4a2713aSLionel Sambuc                                                    ASTContext &Context,
48f4a2713aSLionel Sambuc                                            TemplateTemplateParmDecl *Parameter,
49f4a2713aSLionel Sambuc                                              const TemplateArgument &ArgPack) {
50f4a2713aSLionel Sambuc   ID.AddPointer(Parameter);
51f4a2713aSLionel Sambuc   ArgPack.Profile(ID, Context);
52f4a2713aSLionel Sambuc }
53f4a2713aSLionel Sambuc 
getKind() const54f4a2713aSLionel Sambuc TemplateName::NameKind TemplateName::getKind() const {
55f4a2713aSLionel Sambuc   if (Storage.is<TemplateDecl *>())
56f4a2713aSLionel Sambuc     return Template;
57f4a2713aSLionel Sambuc   if (Storage.is<DependentTemplateName *>())
58f4a2713aSLionel Sambuc     return DependentTemplate;
59f4a2713aSLionel Sambuc   if (Storage.is<QualifiedTemplateName *>())
60f4a2713aSLionel Sambuc     return QualifiedTemplate;
61f4a2713aSLionel Sambuc 
62f4a2713aSLionel Sambuc   UncommonTemplateNameStorage *uncommon
63f4a2713aSLionel Sambuc     = Storage.get<UncommonTemplateNameStorage*>();
64f4a2713aSLionel Sambuc   if (uncommon->getAsOverloadedStorage())
65f4a2713aSLionel Sambuc     return OverloadedTemplate;
66f4a2713aSLionel Sambuc   if (uncommon->getAsSubstTemplateTemplateParm())
67f4a2713aSLionel Sambuc     return SubstTemplateTemplateParm;
68f4a2713aSLionel Sambuc   return SubstTemplateTemplateParmPack;
69f4a2713aSLionel Sambuc }
70f4a2713aSLionel Sambuc 
getAsTemplateDecl() const71f4a2713aSLionel Sambuc TemplateDecl *TemplateName::getAsTemplateDecl() const {
72f4a2713aSLionel Sambuc   if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
73f4a2713aSLionel Sambuc     return Template;
74f4a2713aSLionel Sambuc 
75f4a2713aSLionel Sambuc   if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
76f4a2713aSLionel Sambuc     return QTN->getTemplateDecl();
77f4a2713aSLionel Sambuc 
78f4a2713aSLionel Sambuc   if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
79f4a2713aSLionel Sambuc     return sub->getReplacement().getAsTemplateDecl();
80f4a2713aSLionel Sambuc 
81*0a6a1f1dSLionel Sambuc   return nullptr;
82f4a2713aSLionel Sambuc }
83f4a2713aSLionel Sambuc 
isDependent() const84f4a2713aSLionel Sambuc bool TemplateName::isDependent() const {
85f4a2713aSLionel Sambuc   if (TemplateDecl *Template = getAsTemplateDecl()) {
86f4a2713aSLionel Sambuc     if (isa<TemplateTemplateParmDecl>(Template))
87f4a2713aSLionel Sambuc       return true;
88f4a2713aSLionel Sambuc     // FIXME: Hack, getDeclContext() can be null if Template is still
89f4a2713aSLionel Sambuc     // initializing due to PCH reading, so we check it before using it.
90f4a2713aSLionel Sambuc     // Should probably modify TemplateSpecializationType to allow constructing
91f4a2713aSLionel Sambuc     // it without the isDependent() checking.
92f4a2713aSLionel Sambuc     return Template->getDeclContext() &&
93f4a2713aSLionel Sambuc            Template->getDeclContext()->isDependentContext();
94f4a2713aSLionel Sambuc   }
95f4a2713aSLionel Sambuc 
96f4a2713aSLionel Sambuc   assert(!getAsOverloadedTemplate() &&
97f4a2713aSLionel Sambuc          "overloaded templates shouldn't survive to here");
98f4a2713aSLionel Sambuc 
99f4a2713aSLionel Sambuc   return true;
100f4a2713aSLionel Sambuc }
101f4a2713aSLionel Sambuc 
isInstantiationDependent() const102f4a2713aSLionel Sambuc bool TemplateName::isInstantiationDependent() const {
103f4a2713aSLionel Sambuc   if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
104f4a2713aSLionel Sambuc     if (QTN->getQualifier()->isInstantiationDependent())
105f4a2713aSLionel Sambuc       return true;
106f4a2713aSLionel Sambuc   }
107f4a2713aSLionel Sambuc 
108f4a2713aSLionel Sambuc   return isDependent();
109f4a2713aSLionel Sambuc }
110f4a2713aSLionel Sambuc 
containsUnexpandedParameterPack() const111f4a2713aSLionel Sambuc bool TemplateName::containsUnexpandedParameterPack() const {
112f4a2713aSLionel Sambuc   if (TemplateDecl *Template = getAsTemplateDecl()) {
113f4a2713aSLionel Sambuc     if (TemplateTemplateParmDecl *TTP
114f4a2713aSLionel Sambuc                                   = dyn_cast<TemplateTemplateParmDecl>(Template))
115f4a2713aSLionel Sambuc       return TTP->isParameterPack();
116f4a2713aSLionel Sambuc 
117f4a2713aSLionel Sambuc     return false;
118f4a2713aSLionel Sambuc   }
119f4a2713aSLionel Sambuc 
120f4a2713aSLionel Sambuc   if (DependentTemplateName *DTN = getAsDependentTemplateName())
121f4a2713aSLionel Sambuc     return DTN->getQualifier() &&
122f4a2713aSLionel Sambuc       DTN->getQualifier()->containsUnexpandedParameterPack();
123f4a2713aSLionel Sambuc 
124*0a6a1f1dSLionel Sambuc   return getAsSubstTemplateTemplateParmPack() != nullptr;
125f4a2713aSLionel Sambuc }
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc void
print(raw_ostream & OS,const PrintingPolicy & Policy,bool SuppressNNS) const128f4a2713aSLionel Sambuc TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
129f4a2713aSLionel Sambuc                     bool SuppressNNS) const {
130f4a2713aSLionel Sambuc   if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
131f4a2713aSLionel Sambuc     OS << *Template;
132f4a2713aSLionel Sambuc   else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
133f4a2713aSLionel Sambuc     if (!SuppressNNS)
134f4a2713aSLionel Sambuc       QTN->getQualifier()->print(OS, Policy);
135f4a2713aSLionel Sambuc     if (QTN->hasTemplateKeyword())
136f4a2713aSLionel Sambuc       OS << "template ";
137f4a2713aSLionel Sambuc     OS << *QTN->getDecl();
138f4a2713aSLionel Sambuc   } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
139f4a2713aSLionel Sambuc     if (!SuppressNNS && DTN->getQualifier())
140f4a2713aSLionel Sambuc       DTN->getQualifier()->print(OS, Policy);
141f4a2713aSLionel Sambuc     OS << "template ";
142f4a2713aSLionel Sambuc 
143f4a2713aSLionel Sambuc     if (DTN->isIdentifier())
144f4a2713aSLionel Sambuc       OS << DTN->getIdentifier()->getName();
145f4a2713aSLionel Sambuc     else
146f4a2713aSLionel Sambuc       OS << "operator " << getOperatorSpelling(DTN->getOperator());
147f4a2713aSLionel Sambuc   } else if (SubstTemplateTemplateParmStorage *subst
148f4a2713aSLionel Sambuc                = getAsSubstTemplateTemplateParm()) {
149f4a2713aSLionel Sambuc     subst->getReplacement().print(OS, Policy, SuppressNNS);
150f4a2713aSLionel Sambuc   } else if (SubstTemplateTemplateParmPackStorage *SubstPack
151f4a2713aSLionel Sambuc                                         = getAsSubstTemplateTemplateParmPack())
152f4a2713aSLionel Sambuc     OS << *SubstPack->getParameterPack();
153f4a2713aSLionel Sambuc   else {
154f4a2713aSLionel Sambuc     OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
155f4a2713aSLionel Sambuc     (*OTS->begin())->printName(OS);
156f4a2713aSLionel Sambuc   }
157f4a2713aSLionel Sambuc }
158f4a2713aSLionel Sambuc 
operator <<(const DiagnosticBuilder & DB,TemplateName N)159f4a2713aSLionel Sambuc const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
160f4a2713aSLionel Sambuc                                            TemplateName N) {
161f4a2713aSLionel Sambuc   std::string NameStr;
162f4a2713aSLionel Sambuc   raw_string_ostream OS(NameStr);
163f4a2713aSLionel Sambuc   LangOptions LO;
164f4a2713aSLionel Sambuc   LO.CPlusPlus = true;
165f4a2713aSLionel Sambuc   LO.Bool = true;
166f4a2713aSLionel Sambuc   OS << '\'';
167f4a2713aSLionel Sambuc   N.print(OS, PrintingPolicy(LO));
168f4a2713aSLionel Sambuc   OS << '\'';
169f4a2713aSLionel Sambuc   OS.flush();
170f4a2713aSLionel Sambuc   return DB << NameStr;
171f4a2713aSLionel Sambuc }
172f4a2713aSLionel Sambuc 
dump(raw_ostream & OS) const173f4a2713aSLionel Sambuc void TemplateName::dump(raw_ostream &OS) const {
174f4a2713aSLionel Sambuc   LangOptions LO;  // FIXME!
175f4a2713aSLionel Sambuc   LO.CPlusPlus = true;
176f4a2713aSLionel Sambuc   LO.Bool = true;
177f4a2713aSLionel Sambuc   print(OS, PrintingPolicy(LO));
178f4a2713aSLionel Sambuc }
179f4a2713aSLionel Sambuc 
dump() const180f4a2713aSLionel Sambuc void TemplateName::dump() const {
181f4a2713aSLionel Sambuc   dump(llvm::errs());
182f4a2713aSLionel Sambuc }
183