etc/services - sync with NetBSD-8
[minix.git] / external / bsd / llvm / dist / clang / lib / AST / TemplateName.cpp
blob77c8fd5d1e02222d859da09944c9542513ebef44
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.
12 //===----------------------------------------------------------------------===//
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;
25 TemplateArgument
26 SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
27 return TemplateArgument(Arguments, size());
30 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
31 Profile(ID, Parameter, Replacement);
34 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
35 TemplateTemplateParmDecl *parameter,
36 TemplateName replacement) {
37 ID.AddPointer(parameter);
38 ID.AddPointer(replacement.getAsVoidPointer());
41 void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
42 ASTContext &Context) {
43 Profile(ID, Context, Parameter, TemplateArgument(Arguments, size()));
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);
54 TemplateName::NameKind TemplateName::getKind() const {
55 if (Storage.is<TemplateDecl *>())
56 return Template;
57 if (Storage.is<DependentTemplateName *>())
58 return DependentTemplate;
59 if (Storage.is<QualifiedTemplateName *>())
60 return QualifiedTemplate;
62 UncommonTemplateNameStorage *uncommon
63 = Storage.get<UncommonTemplateNameStorage*>();
64 if (uncommon->getAsOverloadedStorage())
65 return OverloadedTemplate;
66 if (uncommon->getAsSubstTemplateTemplateParm())
67 return SubstTemplateTemplateParm;
68 return SubstTemplateTemplateParmPack;
71 TemplateDecl *TemplateName::getAsTemplateDecl() const {
72 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
73 return Template;
75 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
76 return QTN->getTemplateDecl();
78 if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
79 return sub->getReplacement().getAsTemplateDecl();
81 return nullptr;
84 bool TemplateName::isDependent() const {
85 if (TemplateDecl *Template = getAsTemplateDecl()) {
86 if (isa<TemplateTemplateParmDecl>(Template))
87 return true;
88 // FIXME: Hack, getDeclContext() can be null if Template is still
89 // initializing due to PCH reading, so we check it before using it.
90 // Should probably modify TemplateSpecializationType to allow constructing
91 // it without the isDependent() checking.
92 return Template->getDeclContext() &&
93 Template->getDeclContext()->isDependentContext();
96 assert(!getAsOverloadedTemplate() &&
97 "overloaded templates shouldn't survive to here");
99 return true;
102 bool TemplateName::isInstantiationDependent() const {
103 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
104 if (QTN->getQualifier()->isInstantiationDependent())
105 return true;
108 return isDependent();
111 bool TemplateName::containsUnexpandedParameterPack() const {
112 if (TemplateDecl *Template = getAsTemplateDecl()) {
113 if (TemplateTemplateParmDecl *TTP
114 = dyn_cast<TemplateTemplateParmDecl>(Template))
115 return TTP->isParameterPack();
117 return false;
120 if (DependentTemplateName *DTN = getAsDependentTemplateName())
121 return DTN->getQualifier() &&
122 DTN->getQualifier()->containsUnexpandedParameterPack();
124 return getAsSubstTemplateTemplateParmPack() != nullptr;
127 void
128 TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
129 bool SuppressNNS) const {
130 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
131 OS << *Template;
132 else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
133 if (!SuppressNNS)
134 QTN->getQualifier()->print(OS, Policy);
135 if (QTN->hasTemplateKeyword())
136 OS << "template ";
137 OS << *QTN->getDecl();
138 } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
139 if (!SuppressNNS && DTN->getQualifier())
140 DTN->getQualifier()->print(OS, Policy);
141 OS << "template ";
143 if (DTN->isIdentifier())
144 OS << DTN->getIdentifier()->getName();
145 else
146 OS << "operator " << getOperatorSpelling(DTN->getOperator());
147 } else if (SubstTemplateTemplateParmStorage *subst
148 = getAsSubstTemplateTemplateParm()) {
149 subst->getReplacement().print(OS, Policy, SuppressNNS);
150 } else if (SubstTemplateTemplateParmPackStorage *SubstPack
151 = getAsSubstTemplateTemplateParmPack())
152 OS << *SubstPack->getParameterPack();
153 else {
154 OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
155 (*OTS->begin())->printName(OS);
159 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
160 TemplateName N) {
161 std::string NameStr;
162 raw_string_ostream OS(NameStr);
163 LangOptions LO;
164 LO.CPlusPlus = true;
165 LO.Bool = true;
166 OS << '\'';
167 N.print(OS, PrintingPolicy(LO));
168 OS << '\'';
169 OS.flush();
170 return DB << NameStr;
173 void TemplateName::dump(raw_ostream &OS) const {
174 LangOptions LO; // FIXME!
175 LO.CPlusPlus = true;
176 LO.Bool = true;
177 print(OS, PrintingPolicy(LO));
180 void TemplateName::dump() const {
181 dump(llvm::errs());