blob: 06e1dcec74492f72d0cc7ee89a4a3bf799982c4d [file] [log] [blame]
Eugene Zelenko21fadad2017-11-21 23:26:08 +00001//===- TemplateName.cpp - C++ Template Name Representation ----------------===//
Douglas Gregordc572a32009-03-30 22:58:21 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Douglas Gregordc572a32009-03-30 22:58:21 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the TemplateName interface and subclasses.
10//
11//===----------------------------------------------------------------------===//
Chris Lattner098d94a2009-04-02 06:07:12 +000012
Douglas Gregordc572a32009-03-30 22:58:21 +000013#include "clang/AST/TemplateName.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000014#include "clang/AST/DeclBase.h"
Douglas Gregordc572a32009-03-30 22:58:21 +000015#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"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000020#include "clang/Basic/LLVM.h"
Chris Lattnerc61089a2009-06-30 01:26:17 +000021#include "clang/Basic/LangOptions.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000022#include "clang/Basic/OperatorKinds.h"
23#include "llvm/ADT/ArrayRef.h"
24#include "llvm/ADT/FoldingSet.h"
25#include "llvm/Support/Casting.h"
26#include "llvm/Support/Compiler.h"
Douglas Gregordc572a32009-03-30 22:58:21 +000027#include "llvm/Support/raw_ostream.h"
Eugene Zelenko21fadad2017-11-21 23:26:08 +000028#include <cassert>
29#include <string>
30
Douglas Gregordc572a32009-03-30 22:58:21 +000031using namespace clang;
32
Fangrui Song6907ce22018-07-30 19:24:48 +000033TemplateArgument
Douglas Gregor5590be02011-01-15 06:45:20 +000034SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
Benjamin Kramercce63472015-08-05 09:40:22 +000035 return TemplateArgument(llvm::makeArrayRef(Arguments, size()));
Douglas Gregor5590be02011-01-15 06:45:20 +000036}
37
John McCalld9dfe3a2011-06-30 08:33:18 +000038void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
39 Profile(ID, Parameter, Replacement);
40}
41
Fangrui Song6907ce22018-07-30 19:24:48 +000042void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
John McCalld9dfe3a2011-06-30 08:33:18 +000043 TemplateTemplateParmDecl *parameter,
44 TemplateName replacement) {
45 ID.AddPointer(parameter);
46 ID.AddPointer(replacement.getAsVoidPointer());
47}
48
49void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
50 ASTContext &Context) {
Benjamin Kramercce63472015-08-05 09:40:22 +000051 Profile(ID, Context, Parameter, getArgumentPack());
Douglas Gregor5590be02011-01-15 06:45:20 +000052}
53
Fangrui Song6907ce22018-07-30 19:24:48 +000054void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
Douglas Gregor5590be02011-01-15 06:45:20 +000055 ASTContext &Context,
56 TemplateTemplateParmDecl *Parameter,
57 const TemplateArgument &ArgPack) {
58 ID.AddPointer(Parameter);
59 ArgPack.Profile(ID, Context);
60}
61
Chandler Carruthbd452fb2015-12-30 06:21:02 +000062TemplateName::TemplateName(void *Ptr) {
63 Storage = StorageType::getFromOpaqueValue(Ptr);
64}
65
Chandler Carruth21c90602015-12-30 03:24:14 +000066TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
67TemplateName::TemplateName(OverloadedTemplateStorage *Storage)
68 : Storage(Storage) {}
Richard Smithb23c5e82019-05-09 03:31:27 +000069TemplateName::TemplateName(AssumedTemplateStorage *Storage)
70 : Storage(Storage) {}
Chandler Carruth21c90602015-12-30 03:24:14 +000071TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
72 : Storage(Storage) {}
73TemplateName::TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
74 : Storage(Storage) {}
75TemplateName::TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) {}
76TemplateName::TemplateName(DependentTemplateName *Dep) : Storage(Dep) {}
77
78bool TemplateName::isNull() const { return Storage.isNull(); }
79
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +000080TemplateName::NameKind TemplateName::getKind() const {
81 if (Storage.is<TemplateDecl *>())
82 return Template;
Douglas Gregor5590be02011-01-15 06:45:20 +000083 if (Storage.is<DependentTemplateName *>())
84 return DependentTemplate;
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +000085 if (Storage.is<QualifiedTemplateName *>())
86 return QualifiedTemplate;
John McCalld9dfe3a2011-06-30 08:33:18 +000087
88 UncommonTemplateNameStorage *uncommon
89 = Storage.get<UncommonTemplateNameStorage*>();
90 if (uncommon->getAsOverloadedStorage())
91 return OverloadedTemplate;
Richard Smithb23c5e82019-05-09 03:31:27 +000092 if (uncommon->getAsAssumedTemplateName())
93 return AssumedTemplate;
John McCalld9dfe3a2011-06-30 08:33:18 +000094 if (uncommon->getAsSubstTemplateTemplateParm())
95 return SubstTemplateTemplateParm;
96 return SubstTemplateTemplateParmPack;
Argyrios Kyrtzidis106caf922010-06-19 19:28:53 +000097}
98
Douglas Gregordc572a32009-03-30 22:58:21 +000099TemplateDecl *TemplateName::getAsTemplateDecl() const {
100 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
101 return Template;
Mike Stump11289f42009-09-09 15:08:12 +0000102
Douglas Gregordc572a32009-03-30 22:58:21 +0000103 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
104 return QTN->getTemplateDecl();
105
John McCalld9dfe3a2011-06-30 08:33:18 +0000106 if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
107 return sub->getReplacement().getAsTemplateDecl();
108
Craig Topper36250ad2014-05-12 05:36:57 +0000109 return nullptr;
Douglas Gregordc572a32009-03-30 22:58:21 +0000110}
111
Chandler Carruth21c90602015-12-30 03:24:14 +0000112OverloadedTemplateStorage *TemplateName::getAsOverloadedTemplate() const {
113 if (UncommonTemplateNameStorage *Uncommon =
114 Storage.dyn_cast<UncommonTemplateNameStorage *>())
115 return Uncommon->getAsOverloadedStorage();
116
117 return nullptr;
118}
119
Richard Smithb23c5e82019-05-09 03:31:27 +0000120AssumedTemplateStorage *TemplateName::getAsAssumedTemplateName() const {
121 if (UncommonTemplateNameStorage *Uncommon =
122 Storage.dyn_cast<UncommonTemplateNameStorage *>())
123 return Uncommon->getAsAssumedTemplateName();
124
125 return nullptr;
126}
127
Chandler Carruth21c90602015-12-30 03:24:14 +0000128SubstTemplateTemplateParmStorage *
129TemplateName::getAsSubstTemplateTemplateParm() const {
130 if (UncommonTemplateNameStorage *uncommon =
131 Storage.dyn_cast<UncommonTemplateNameStorage *>())
132 return uncommon->getAsSubstTemplateTemplateParm();
133
134 return nullptr;
135}
136
137SubstTemplateTemplateParmPackStorage *
138TemplateName::getAsSubstTemplateTemplateParmPack() const {
139 if (UncommonTemplateNameStorage *Uncommon =
140 Storage.dyn_cast<UncommonTemplateNameStorage *>())
141 return Uncommon->getAsSubstTemplateTemplateParmPack();
142
143 return nullptr;
144}
145
146QualifiedTemplateName *TemplateName::getAsQualifiedTemplateName() const {
147 return Storage.dyn_cast<QualifiedTemplateName *>();
148}
149
150DependentTemplateName *TemplateName::getAsDependentTemplateName() const {
151 return Storage.dyn_cast<DependentTemplateName *>();
152}
153
Richard Smith1abacfc2017-08-29 22:14:43 +0000154TemplateName TemplateName::getNameToSubstitute() const {
155 TemplateDecl *Decl = getAsTemplateDecl();
156
157 // Substituting a dependent template name: preserve it as written.
158 if (!Decl)
159 return *this;
160
161 // If we have a template declaration, use the most recent non-friend
162 // declaration of that template.
163 Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
164 while (Decl->getFriendObjectKind()) {
165 Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
166 assert(Decl && "all declarations of template are friends");
167 }
168 return TemplateName(Decl);
169}
170
Douglas Gregordc572a32009-03-30 22:58:21 +0000171bool TemplateName::isDependent() const {
172 if (TemplateDecl *Template = getAsTemplateDecl()) {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000173 if (isa<TemplateTemplateParmDecl>(Template))
174 return true;
175 // FIXME: Hack, getDeclContext() can be null if Template is still
176 // initializing due to PCH reading, so we check it before using it.
177 // Should probably modify TemplateSpecializationType to allow constructing
178 // it without the isDependent() checking.
179 return Template->getDeclContext() &&
180 Template->getDeclContext()->isDependentContext();
Douglas Gregordc572a32009-03-30 22:58:21 +0000181 }
182
John McCalld28ae272009-12-02 08:04:21 +0000183 assert(!getAsOverloadedTemplate() &&
184 "overloaded templates shouldn't survive to here");
Mike Stump11289f42009-09-09 15:08:12 +0000185
Douglas Gregordc572a32009-03-30 22:58:21 +0000186 return true;
187}
188
Douglas Gregor678d76c2011-07-01 01:22:09 +0000189bool TemplateName::isInstantiationDependent() const {
190 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
191 if (QTN->getQualifier()->isInstantiationDependent())
192 return true;
193 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000194
Douglas Gregor678d76c2011-07-01 01:22:09 +0000195 return isDependent();
196}
197
Douglas Gregor506bd562010-12-13 22:49:22 +0000198bool TemplateName::containsUnexpandedParameterPack() const {
Richard Smith77a9c602018-02-28 03:02:23 +0000199 if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
200 if (QTN->getQualifier()->containsUnexpandedParameterPack())
201 return true;
202 }
203
Douglas Gregor506bd562010-12-13 22:49:22 +0000204 if (TemplateDecl *Template = getAsTemplateDecl()) {
Fangrui Song6907ce22018-07-30 19:24:48 +0000205 if (TemplateTemplateParmDecl *TTP
Douglas Gregor506bd562010-12-13 22:49:22 +0000206 = dyn_cast<TemplateTemplateParmDecl>(Template))
207 return TTP->isParameterPack();
208
209 return false;
210 }
211
212 if (DependentTemplateName *DTN = getAsDependentTemplateName())
Fangrui Song6907ce22018-07-30 19:24:48 +0000213 return DTN->getQualifier() &&
Douglas Gregor506bd562010-12-13 22:49:22 +0000214 DTN->getQualifier()->containsUnexpandedParameterPack();
215
Craig Topper36250ad2014-05-12 05:36:57 +0000216 return getAsSubstTemplateTemplateParmPack() != nullptr;
Douglas Gregor506bd562010-12-13 22:49:22 +0000217}
218
Mike Stump11289f42009-09-09 15:08:12 +0000219void
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000220TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
Douglas Gregor7de59662009-05-29 20:38:28 +0000221 bool SuppressNNS) const {
Douglas Gregordc572a32009-03-30 22:58:21 +0000222 if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
Benjamin Kramerb89514a2011-10-14 18:45:37 +0000223 OS << *Template;
Douglas Gregordc572a32009-03-30 22:58:21 +0000224 else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
Douglas Gregordce2b622009-04-01 00:28:59 +0000225 if (!SuppressNNS)
Douglas Gregor7de59662009-05-29 20:38:28 +0000226 QTN->getQualifier()->print(OS, Policy);
Douglas Gregordc572a32009-03-30 22:58:21 +0000227 if (QTN->hasTemplateKeyword())
228 OS << "template ";
Benjamin Kramerb89514a2011-10-14 18:45:37 +0000229 OS << *QTN->getDecl();
Douglas Gregordc572a32009-03-30 22:58:21 +0000230 } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
Douglas Gregor308047d2009-09-09 00:23:06 +0000231 if (!SuppressNNS && DTN->getQualifier())
Douglas Gregor7de59662009-05-29 20:38:28 +0000232 DTN->getQualifier()->print(OS, Policy);
Douglas Gregordc572a32009-03-30 22:58:21 +0000233 OS << "template ";
Fangrui Song6907ce22018-07-30 19:24:48 +0000234
Douglas Gregor71395fa2009-11-04 00:56:37 +0000235 if (DTN->isIdentifier())
236 OS << DTN->getIdentifier()->getName();
237 else
238 OS << "operator " << getOperatorSpelling(DTN->getOperator());
John McCalld9dfe3a2011-06-30 08:33:18 +0000239 } else if (SubstTemplateTemplateParmStorage *subst
240 = getAsSubstTemplateTemplateParm()) {
241 subst->getReplacement().print(OS, Policy, SuppressNNS);
Douglas Gregor5590be02011-01-15 06:45:20 +0000242 } else if (SubstTemplateTemplateParmPackStorage *SubstPack
243 = getAsSubstTemplateTemplateParmPack())
Benjamin Kramerdb0fc512012-02-07 11:57:57 +0000244 OS << *SubstPack->getParameterPack();
Richard Smithb23c5e82019-05-09 03:31:27 +0000245 else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
246 Assumed->getDeclName().print(OS, Policy);
247 } else {
Douglas Gregor8b6070b2011-03-04 21:37:14 +0000248 OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
249 (*OTS->begin())->printName(OS);
250 }
Douglas Gregordc572a32009-03-30 22:58:21 +0000251}
Douglas Gregoraa594892009-03-31 18:38:02 +0000252
Jeffrey Yasskin823015d2010-04-08 00:03:06 +0000253const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
254 TemplateName N) {
255 std::string NameStr;
Eugene Zelenko21fadad2017-11-21 23:26:08 +0000256 llvm::raw_string_ostream OS(NameStr);
Jeffrey Yasskin823015d2010-04-08 00:03:06 +0000257 LangOptions LO;
258 LO.CPlusPlus = true;
259 LO.Bool = true;
David Blaikiee7504912013-03-05 06:21:38 +0000260 OS << '\'';
Jeffrey Yasskin823015d2010-04-08 00:03:06 +0000261 N.print(OS, PrintingPolicy(LO));
David Blaikiee7504912013-03-05 06:21:38 +0000262 OS << '\'';
Jeffrey Yasskin823015d2010-04-08 00:03:06 +0000263 OS.flush();
264 return DB << NameStr;
265}
266
David Blaikie5e328052019-05-03 00:44:50 +0000267const PartialDiagnostic&clang::operator<<(const PartialDiagnostic &PD,
268 TemplateName N) {
269 std::string NameStr;
270 llvm::raw_string_ostream OS(NameStr);
271 LangOptions LO;
272 LO.CPlusPlus = true;
273 LO.Bool = true;
274 OS << '\'';
275 N.print(OS, PrintingPolicy(LO));
276 OS << '\'';
277 OS.flush();
278 return PD << NameStr;
279}
280
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000281void TemplateName::dump(raw_ostream &OS) const {
Chris Lattnerc61089a2009-06-30 01:26:17 +0000282 LangOptions LO; // FIXME!
283 LO.CPlusPlus = true;
284 LO.Bool = true;
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000285 print(OS, PrintingPolicy(LO));
286}
287
Yaron Kerencdae9412016-01-29 19:38:18 +0000288LLVM_DUMP_METHOD void TemplateName::dump() const {
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000289 dump(llvm::errs());
Douglas Gregoraa594892009-03-31 18:38:02 +0000290}