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