blob: 47a7d47e7a489875e388992a776a16836f322caf [file] [log] [blame]
Chandler Carruth3a022472012-12-04 09:13:33 +00001//===--- TemplateName.cpp - C++ Template Name Representation---------------===//
Douglas Gregordc572a32009-03-30 22:58:21 +00002//
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//===----------------------------------------------------------------------===//
Chris Lattner098d94a2009-04-02 06:07:12 +000013
Douglas Gregordc572a32009-03-30 22:58:21 +000014#include "clang/AST/TemplateName.h"
15#include "clang/AST/DeclTemplate.h"
16#include "clang/AST/NestedNameSpecifier.h"
Douglas Gregor7de59662009-05-29 20:38:28 +000017#include "clang/AST/PrettyPrinter.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000018#include "clang/AST/TemplateBase.h"
Jeffrey Yasskin823015d2010-04-08 00:03:06 +000019#include "clang/Basic/Diagnostic.h"
Chris Lattnerc61089a2009-06-30 01:26:17 +000020#include "clang/Basic/LangOptions.h"
Douglas Gregordc572a32009-03-30 22:58:21 +000021#include "llvm/Support/raw_ostream.h"
Douglas Gregordc572a32009-03-30 22:58:21 +000022using namespace clang;
Jeffrey Yasskin823015d2010-04-08 00:03:06 +000023using namespace llvm;
Douglas Gregordc572a32009-03-30 22:58:21 +000024
Douglas Gregor5590be02011-01-15 06:45:20 +000025TemplateArgument
26SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
Benjamin Kramercce63472015-08-05 09:40:22 +000027 return TemplateArgument(llvm::makeArrayRef(Arguments, size()));
Douglas Gregor5590be02011-01-15 06:45:20 +000028}
29
John McCalld9dfe3a2011-06-30 08:33:18 +000030void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
31 Profile(ID, Parameter, Replacement);
32}
33
34void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
35 TemplateTemplateParmDecl *parameter,
36 TemplateName replacement) {
37 ID.AddPointer(parameter);
38 ID.AddPointer(replacement.getAsVoidPointer());
39}
40
41void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
42 ASTContext &Context) {
Benjamin Kramercce63472015-08-05 09:40:22 +000043 Profile(ID, Context, Parameter, getArgumentPack());
Douglas Gregor5590be02011-01-15 06:45:20 +000044}
45
46void 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
Chandler Carruthbd452fb2015-12-30 06:21:02 +000054TemplateName::TemplateName(void *Ptr) {
55 Storage = StorageType::getFromOpaqueValue(Ptr);
56}
57
Chandler Carruth21c90602015-12-30 03:24:14 +000058TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
59TemplateName::TemplateName(OverloadedTemplateStorage *Storage)
60 : Storage(Storage) {}
61TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
62 : Storage(Storage) {}
63TemplateName::TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
64 : Storage(Storage) {}
65TemplateName::TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) {}
66TemplateName::TemplateName(DependentTemplateName *Dep) : Storage(Dep) {}
67
68bool TemplateName::isNull() const { return Storage.isNull(); }
69
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +000070TemplateName::NameKind TemplateName::getKind() const {
71 if (Storage.is<TemplateDecl *>())
72 return Template;
Douglas Gregor5590be02011-01-15 06:45:20 +000073 if (Storage.is<DependentTemplateName *>())
74 return DependentTemplate;
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +000075 if (Storage.is<QualifiedTemplateName *>())
76 return QualifiedTemplate;
John McCalld9dfe3a2011-06-30 08:33:18 +000077
78 UncommonTemplateNameStorage *uncommon
79 = Storage.get<UncommonTemplateNameStorage*>();
80 if (uncommon->getAsOverloadedStorage())
81 return OverloadedTemplate;
82 if (uncommon->getAsSubstTemplateTemplateParm())
83 return SubstTemplateTemplateParm;
84 return SubstTemplateTemplateParmPack;
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +000085}
86
Douglas Gregordc572a32009-03-30 22:58:21 +000087TemplateDecl *TemplateName::getAsTemplateDecl() const {
88 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
89 return Template;
Mike Stump11289f42009-09-09 15:08:12 +000090
Douglas Gregordc572a32009-03-30 22:58:21 +000091 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
92 return QTN->getTemplateDecl();
93
John McCalld9dfe3a2011-06-30 08:33:18 +000094 if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
95 return sub->getReplacement().getAsTemplateDecl();
96
Craig Topper36250ad2014-05-12 05:36:57 +000097 return nullptr;
Douglas Gregordc572a32009-03-30 22:58:21 +000098}
99
Chandler Carruth21c90602015-12-30 03:24:14 +0000100OverloadedTemplateStorage *TemplateName::getAsOverloadedTemplate() const {
101 if (UncommonTemplateNameStorage *Uncommon =
102 Storage.dyn_cast<UncommonTemplateNameStorage *>())
103 return Uncommon->getAsOverloadedStorage();
104
105 return nullptr;
106}
107
108SubstTemplateTemplateParmStorage *
109TemplateName::getAsSubstTemplateTemplateParm() const {
110 if (UncommonTemplateNameStorage *uncommon =
111 Storage.dyn_cast<UncommonTemplateNameStorage *>())
112 return uncommon->getAsSubstTemplateTemplateParm();
113
114 return nullptr;
115}
116
117SubstTemplateTemplateParmPackStorage *
118TemplateName::getAsSubstTemplateTemplateParmPack() const {
119 if (UncommonTemplateNameStorage *Uncommon =
120 Storage.dyn_cast<UncommonTemplateNameStorage *>())
121 return Uncommon->getAsSubstTemplateTemplateParmPack();
122
123 return nullptr;
124}
125
126QualifiedTemplateName *TemplateName::getAsQualifiedTemplateName() const {
127 return Storage.dyn_cast<QualifiedTemplateName *>();
128}
129
130DependentTemplateName *TemplateName::getAsDependentTemplateName() const {
131 return Storage.dyn_cast<DependentTemplateName *>();
132}
133
Douglas Gregordc572a32009-03-30 22:58:21 +0000134bool TemplateName::isDependent() const {
135 if (TemplateDecl *Template = getAsTemplateDecl()) {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000136 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();
Douglas Gregordc572a32009-03-30 22:58:21 +0000144 }
145
John McCalld28ae272009-12-02 08:04:21 +0000146 assert(!getAsOverloadedTemplate() &&
147 "overloaded templates shouldn't survive to here");
Mike Stump11289f42009-09-09 15:08:12 +0000148
Douglas Gregordc572a32009-03-30 22:58:21 +0000149 return true;
150}
151
Douglas Gregor678d76c2011-07-01 01:22:09 +0000152bool TemplateName::isInstantiationDependent() const {
153 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
154 if (QTN->getQualifier()->isInstantiationDependent())
155 return true;
156 }
157
158 return isDependent();
159}
160
Douglas Gregor506bd562010-12-13 22:49:22 +0000161bool 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
Craig Topper36250ad2014-05-12 05:36:57 +0000174 return getAsSubstTemplateTemplateParmPack() != nullptr;
Douglas Gregor506bd562010-12-13 22:49:22 +0000175}
176
Mike Stump11289f42009-09-09 15:08:12 +0000177void
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000178TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
Douglas Gregor7de59662009-05-29 20:38:28 +0000179 bool SuppressNNS) const {
Douglas Gregordc572a32009-03-30 22:58:21 +0000180 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
Benjamin Kramerb89514a2011-10-14 18:45:37 +0000181 OS << *Template;
Douglas Gregordc572a32009-03-30 22:58:21 +0000182 else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
Douglas Gregordce2b622009-04-01 00:28:59 +0000183 if (!SuppressNNS)
Douglas Gregor7de59662009-05-29 20:38:28 +0000184 QTN->getQualifier()->print(OS, Policy);
Douglas Gregordc572a32009-03-30 22:58:21 +0000185 if (QTN->hasTemplateKeyword())
186 OS << "template ";
Benjamin Kramerb89514a2011-10-14 18:45:37 +0000187 OS << *QTN->getDecl();
Douglas Gregordc572a32009-03-30 22:58:21 +0000188 } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
Douglas Gregor308047d2009-09-09 00:23:06 +0000189 if (!SuppressNNS && DTN->getQualifier())
Douglas Gregor7de59662009-05-29 20:38:28 +0000190 DTN->getQualifier()->print(OS, Policy);
Douglas Gregordc572a32009-03-30 22:58:21 +0000191 OS << "template ";
Douglas Gregor71395fa2009-11-04 00:56:37 +0000192
193 if (DTN->isIdentifier())
194 OS << DTN->getIdentifier()->getName();
195 else
196 OS << "operator " << getOperatorSpelling(DTN->getOperator());
John McCalld9dfe3a2011-06-30 08:33:18 +0000197 } else if (SubstTemplateTemplateParmStorage *subst
198 = getAsSubstTemplateTemplateParm()) {
199 subst->getReplacement().print(OS, Policy, SuppressNNS);
Douglas Gregor5590be02011-01-15 06:45:20 +0000200 } else if (SubstTemplateTemplateParmPackStorage *SubstPack
201 = getAsSubstTemplateTemplateParmPack())
Benjamin Kramerdb0fc512012-02-07 11:57:57 +0000202 OS << *SubstPack->getParameterPack();
Douglas Gregor8b6070b2011-03-04 21:37:14 +0000203 else {
204 OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
205 (*OTS->begin())->printName(OS);
206 }
Douglas Gregordc572a32009-03-30 22:58:21 +0000207}
Douglas Gregoraa594892009-03-31 18:38:02 +0000208
Jeffrey Yasskin823015d2010-04-08 00:03:06 +0000209const 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;
David Blaikiee7504912013-03-05 06:21:38 +0000216 OS << '\'';
Jeffrey Yasskin823015d2010-04-08 00:03:06 +0000217 N.print(OS, PrintingPolicy(LO));
David Blaikiee7504912013-03-05 06:21:38 +0000218 OS << '\'';
Jeffrey Yasskin823015d2010-04-08 00:03:06 +0000219 OS.flush();
220 return DB << NameStr;
221}
222
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000223void TemplateName::dump(raw_ostream &OS) const {
Chris Lattnerc61089a2009-06-30 01:26:17 +0000224 LangOptions LO; // FIXME!
225 LO.CPlusPlus = true;
226 LO.Bool = true;
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000227 print(OS, PrintingPolicy(LO));
228}
229
Yaron Kerencdae9412016-01-29 19:38:18 +0000230LLVM_DUMP_METHOD void TemplateName::dump() const {
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000231 dump(llvm::errs());
Douglas Gregoraa594892009-03-31 18:38:02 +0000232}