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/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
;
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
,
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
*>())
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
*>())
75 if (QualifiedTemplateName
*QTN
= getAsQualifiedTemplateName())
76 return QTN
->getTemplateDecl();
78 if (SubstTemplateTemplateParmStorage
*sub
= getAsSubstTemplateTemplateParm())
79 return sub
->getReplacement().getAsTemplateDecl();
84 bool TemplateName::isDependent() const {
85 if (TemplateDecl
*Template
= getAsTemplateDecl()) {
86 if (isa
<TemplateTemplateParmDecl
>(Template
))
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");
102 bool TemplateName::isInstantiationDependent() const {
103 if (QualifiedTemplateName
*QTN
= getAsQualifiedTemplateName()) {
104 if (QTN
->getQualifier()->isInstantiationDependent())
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();
120 if (DependentTemplateName
*DTN
= getAsDependentTemplateName())
121 return DTN
->getQualifier() &&
122 DTN
->getQualifier()->containsUnexpandedParameterPack();
124 return getAsSubstTemplateTemplateParmPack() != nullptr;
128 TemplateName::print(raw_ostream
&OS
, const PrintingPolicy
&Policy
,
129 bool SuppressNNS
) const {
130 if (TemplateDecl
*Template
= Storage
.dyn_cast
<TemplateDecl
*>())
132 else if (QualifiedTemplateName
*QTN
= getAsQualifiedTemplateName()) {
134 QTN
->getQualifier()->print(OS
, Policy
);
135 if (QTN
->hasTemplateKeyword())
137 OS
<< *QTN
->getDecl();
138 } else if (DependentTemplateName
*DTN
= getAsDependentTemplateName()) {
139 if (!SuppressNNS
&& DTN
->getQualifier())
140 DTN
->getQualifier()->print(OS
, Policy
);
143 if (DTN
->isIdentifier())
144 OS
<< DTN
->getIdentifier()->getName();
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();
154 OverloadedTemplateStorage
*OTS
= getAsOverloadedTemplate();
155 (*OTS
->begin())->printName(OS
);
159 const DiagnosticBuilder
&clang::operator<<(const DiagnosticBuilder
&DB
,
162 raw_string_ostream
OS(NameStr
);
167 N
.print(OS
, PrintingPolicy(LO
));
170 return DB
<< NameStr
;
173 void TemplateName::dump(raw_ostream
&OS
) const {
174 LangOptions LO
; // FIXME!
177 print(OS
, PrintingPolicy(LO
));
180 void TemplateName::dump() const {