clang  16.0.0git
TemplateName.cpp
Go to the documentation of this file.
1 //===- TemplateName.cpp - C++ Template Name Representation ----------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the TemplateName interface and subclasses.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/TemplateName.h"
14 #include "clang/AST/Decl.h"
15 #include "clang/AST/DeclBase.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/TemplateBase.h"
22 #include "clang/Basic/Diagnostic.h"
23 #include "clang/Basic/LLVM.h"
26 #include "llvm/ADT/ArrayRef.h"
27 #include "llvm/ADT/FoldingSet.h"
28 #include "llvm/Support/Casting.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/raw_ostream.h"
31 #include <cassert>
32 #include <string>
33 
34 using namespace clang;
35 
38  return TemplateArgument(llvm::makeArrayRef(Arguments, Bits.Data));
39 }
40 
43  return cast<TemplateTemplateParmDecl>(
45  ->asArray()[Bits.Index]);
46 }
47 
50  return cast<TemplateTemplateParmDecl>(
52  ->asArray()[Bits.Index]);
53 }
54 
55 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
56  Profile(ID, Replacement, getAssociatedDecl(), getIndex(), getPackIndex());
57 }
58 
59 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
60  TemplateName Replacement,
61  Decl *AssociatedDecl,
62  unsigned Index,
63  Optional<unsigned> PackIndex) {
64  Replacement.Profile(ID);
65  ID.AddPointer(AssociatedDecl);
66  ID.AddInteger(Index);
67  ID.AddInteger(PackIndex ? *PackIndex + 1 : 0);
68 }
69 
71  ArrayRef<TemplateArgument> ArgPack, Decl *AssociatedDecl, unsigned Index,
72  bool Final)
73  : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Index,
74  ArgPack.size()),
75  Arguments(ArgPack.data()), AssociatedDeclAndFinal(AssociatedDecl, Final) {
76  assert(AssociatedDecl != nullptr);
77 }
78 
80  ASTContext &Context) {
82  getFinal());
83 }
84 
86  return AssociatedDeclAndFinal.getPointer();
87 }
88 
90  return AssociatedDeclAndFinal.getInt();
91 }
92 
94  llvm::FoldingSetNodeID &ID, ASTContext &Context,
95  const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index,
96  bool Final) {
97  ArgPack.Profile(ID, Context);
98  ID.AddPointer(AssociatedDecl);
99  ID.AddInteger(Index);
100  ID.AddBoolean(Final);
101 }
102 
103 TemplateName::TemplateName(void *Ptr) {
104  Storage = StorageType::getFromOpaqueValue(Ptr);
105 }
106 
107 TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
109  : Storage(Storage) {}
111  : Storage(Storage) {}
113  : Storage(Storage) {}
115  : Storage(Storage) {}
118 TemplateName::TemplateName(UsingShadowDecl *Using) : Storage(Using) {}
119 
120 bool TemplateName::isNull() const { return Storage.isNull(); }
121 
123  if (auto *ND = Storage.dyn_cast<Decl *>()) {
124  if (isa<UsingShadowDecl>(ND))
125  return UsingTemplate;
126  assert(isa<TemplateDecl>(ND));
127  return Template;
128  }
129 
130  if (Storage.is<DependentTemplateName *>())
131  return DependentTemplate;
132  if (Storage.is<QualifiedTemplateName *>())
133  return QualifiedTemplate;
134 
136  = Storage.get<UncommonTemplateNameStorage*>();
137  if (uncommon->getAsOverloadedStorage())
138  return OverloadedTemplate;
139  if (uncommon->getAsAssumedTemplateName())
140  return AssumedTemplate;
141  if (uncommon->getAsSubstTemplateTemplateParm())
144 }
145 
147  if (Decl *TemplateOrUsing = Storage.dyn_cast<Decl *>()) {
148  if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(TemplateOrUsing))
149  return cast<TemplateDecl>(USD->getTargetDecl());
150 
151  assert(isa<TemplateDecl>(TemplateOrUsing));
152  return cast<TemplateDecl>(TemplateOrUsing);
153  }
154 
156  return QTN->getUnderlyingTemplate().getAsTemplateDecl();
157 
159  return sub->getReplacement().getAsTemplateDecl();
160 
162  return cast<TemplateDecl>(USD->getTargetDecl());
163 
164  return nullptr;
165 }
166 
168  if (UncommonTemplateNameStorage *Uncommon =
169  Storage.dyn_cast<UncommonTemplateNameStorage *>())
170  return Uncommon->getAsOverloadedStorage();
171 
172  return nullptr;
173 }
174 
176  if (UncommonTemplateNameStorage *Uncommon =
177  Storage.dyn_cast<UncommonTemplateNameStorage *>())
178  return Uncommon->getAsAssumedTemplateName();
179 
180  return nullptr;
181 }
182 
185  if (UncommonTemplateNameStorage *uncommon =
186  Storage.dyn_cast<UncommonTemplateNameStorage *>())
187  return uncommon->getAsSubstTemplateTemplateParm();
188 
189  return nullptr;
190 }
191 
194  if (UncommonTemplateNameStorage *Uncommon =
195  Storage.dyn_cast<UncommonTemplateNameStorage *>())
196  return Uncommon->getAsSubstTemplateTemplateParmPack();
197 
198  return nullptr;
199 }
200 
202  return Storage.dyn_cast<QualifiedTemplateName *>();
203 }
204 
206  return Storage.dyn_cast<DependentTemplateName *>();
207 }
208 
210  if (Decl *D = Storage.dyn_cast<Decl *>())
211  if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D))
212  return USD;
214  return QTN->getUnderlyingTemplate().getAsUsingShadowDecl();
215  return nullptr;
216 }
217 
220 
221  // Substituting a dependent template name: preserve it as written.
222  if (!Decl)
223  return *this;
224 
225  // If we have a template declaration, use the most recent non-friend
226  // declaration of that template.
227  Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
228  while (Decl->getFriendObjectKind()) {
229  Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
230  assert(Decl && "all declarations of template are friends");
231  }
232  return TemplateName(Decl);
233 }
234 
235 TemplateNameDependence TemplateName::getDependence() const {
237  switch (getKind()) {
238  case TemplateName::NameKind::QualifiedTemplate:
240  getAsQualifiedTemplateName()->getQualifier()->getDependence());
241  break;
242  case TemplateName::NameKind::DependentTemplate:
244  getAsDependentTemplateName()->getQualifier()->getDependence());
245  break;
246  case TemplateName::NameKind::SubstTemplateTemplateParmPack:
247  D |= TemplateNameDependence::UnexpandedPack;
248  break;
249  case TemplateName::NameKind::OverloadedTemplate:
250  llvm_unreachable("overloaded templates shouldn't survive to here.");
251  default:
252  break;
253  }
255  if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) {
256  D |= TemplateNameDependence::DependentInstantiation;
257  if (TTP->isParameterPack())
258  D |= TemplateNameDependence::UnexpandedPack;
259  }
260  // FIXME: Hack, getDeclContext() can be null if Template is still
261  // initializing due to PCH reading, so we check it before using it.
262  // Should probably modify TemplateSpecializationType to allow constructing
263  // it without the isDependent() checking.
264  if (Template->getDeclContext() &&
265  Template->getDeclContext()->isDependentContext())
266  D |= TemplateNameDependence::DependentInstantiation;
267  } else {
268  D |= TemplateNameDependence::DependentInstantiation;
269  }
270  return D;
271 }
272 
274  return getDependence() & TemplateNameDependence::Dependent;
275 }
276 
278  return getDependence() & TemplateNameDependence::Instantiation;
279 }
280 
282  return getDependence() & TemplateNameDependence::UnexpandedPack;
283 }
284 
285 void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
286  Qualified Qual) const {
287  auto Kind = getKind();
288  TemplateDecl *Template = nullptr;
290  // After `namespace ns { using std::vector }`, what is the fully-qualified
291  // name of the UsingTemplateName `vector` within ns?
292  //
293  // - ns::vector (the qualified name of the using-shadow decl)
294  // - std::vector (the qualified name of the underlying template decl)
295  //
296  // Similar to the UsingType behavior, using declarations are used to import
297  // names more often than to export them, thus using the original name is
298  // most useful in this case.
300  }
301 
302  if (Template)
303  if (Policy.CleanUglifiedParameters &&
304  isa<TemplateTemplateParmDecl>(Template) && Template->getIdentifier())
305  OS << Template->getIdentifier()->deuglifiedName();
306  else if (Qual == Qualified::Fully &&
307  getDependence() !=
308  TemplateNameDependenceScope::DependentInstantiation)
309  Template->printQualifiedName(OS, Policy);
310  else
311  OS << *Template;
313  if (Qual == Qualified::Fully &&
314  getDependence() !=
315  TemplateNameDependenceScope::DependentInstantiation) {
316  QTN->getUnderlyingTemplate().getAsTemplateDecl()->printQualifiedName(
317  OS, Policy);
318  return;
319  }
320  if (Qual == Qualified::AsWritten)
321  QTN->getQualifier()->print(OS, Policy);
322  if (QTN->hasTemplateKeyword())
323  OS << "template ";
324  OS << *QTN->getUnderlyingTemplate().getAsTemplateDecl();
326  if (Qual == Qualified::AsWritten && DTN->getQualifier())
327  DTN->getQualifier()->print(OS, Policy);
328  OS << "template ";
329 
330  if (DTN->isIdentifier())
331  OS << DTN->getIdentifier()->getName();
332  else
333  OS << "operator " << getOperatorSpelling(DTN->getOperator());
334  } else if (SubstTemplateTemplateParmStorage *subst
336  subst->getReplacement().print(OS, Policy, Qual);
337  } else if (SubstTemplateTemplateParmPackStorage *SubstPack
339  OS << *SubstPack->getParameterPack();
340  else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
341  Assumed->getDeclName().print(OS, Policy);
342  } else {
345  (*OTS->begin())->printName(OS, Policy);
346  }
347 }
348 
350  TemplateName N) {
351  std::string NameStr;
352  llvm::raw_string_ostream OS(NameStr);
353  LangOptions LO;
354  LO.CPlusPlus = true;
355  LO.Bool = true;
356  OS << '\'';
357  N.print(OS, PrintingPolicy(LO));
358  OS << '\'';
359  OS.flush();
360  return DB << NameStr;
361 }
362 
363 void TemplateName::dump(raw_ostream &OS) const {
364  LangOptions LO; // FIXME!
365  LO.CPlusPlus = true;
366  LO.Bool = true;
367  print(OS, PrintingPolicy(LO));
368 }
369 
370 LLVM_DUMP_METHOD void TemplateName::dump() const {
371  dump(llvm::errs());
372 }
clang::TemplateName::Qualified::AsWritten
@ AsWritten
clang::SubstTemplateTemplateParmPackStorage::getArgumentPack
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
Definition: TemplateName.cpp:37
clang::TemplateName::isInstantiationDependent
bool isInstantiationDependent() const
Determines whether this is a template name that somehow depends on a template parameter.
Definition: TemplateName.cpp:277
clang::TemplateName::Qualified::Fully
@ Fully
clang::TemplateName::getAsSubstTemplateTemplateParm
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm() const
Retrieve the substituted template template parameter, if known.
Definition: TemplateName.cpp:184
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::SubstTemplateTemplateParmPackStorage::getAssociatedDecl
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
Definition: TemplateName.cpp:85
clang::TemplateName::containsUnexpandedParameterPack
bool containsUnexpandedParameterPack() const
Determines whether this template name contains an unexpanded parameter pack (for C++0x variadic templ...
Definition: TemplateName.cpp:281
DependenceFlags.h
clang::UncommonTemplateNameStorage::getAsAssumedTemplateName
AssumedTemplateStorage * getAsAssumedTemplateName()
Definition: TemplateName.h:86
clang::TemplateArgument::Profile
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
Definition: TemplateBase.cpp:307
clang::TemplateName::getAsTemplateDecl
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
Definition: TemplateName.cpp:146
clang::toTemplateNameDependence
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
Definition: DependenceFlags.h:314
clang::OverloadedTemplateStorage
A structure for storing the information associated with an overloaded template name.
Definition: TemplateName.h:107
DeclCXX.h
clang::UsingShadowDecl
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3222
clang::TemplateName::getDependence
TemplateNameDependence getDependence() const
Definition: TemplateName.cpp:235
llvm::Optional< unsigned >
clang::TemplateName::getAsOverloadedTemplate
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template declarations that this template name refers to,...
Definition: TemplateName.cpp:167
clang::SubstTemplateTemplateParmStorage::getParameter
TemplateTemplateParmDecl * getParameter() const
Definition: TemplateName.cpp:49
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
clang::UncommonTemplateNameStorage::getAsOverloadedStorage
OverloadedTemplateStorage * getAsOverloadedStorage()
Definition: TemplateName.h:80
clang::TemplateName::getNameToSubstitute
TemplateName getNameToSubstitute() const
Get the template name to substitute when this template name is used as a template template argument.
Definition: TemplateName.cpp:218
TemplateName.h
Decl.h
PrettyPrinter.h
clang::SubstTemplateTemplateParmStorage::getPackIndex
Optional< unsigned > getPackIndex() const
Definition: TemplateName.h:398
TemplateBase.h
clang::TemplateName::isDependent
bool isDependent() const
Determines whether this is a dependent template name.
Definition: TemplateName.cpp:273
clang::SubstTemplateTemplateParmStorage::getIndex
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
Definition: TemplateName.h:396
DeclTemplate.h
DeclBase.h
clang::XRayInstrKind::None
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
OperatorKinds.h
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
clang::OverloadedTemplateStorage::begin
iterator begin() const
Definition: TemplateName.h:125
clang::StreamingDiagnostic
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
Definition: Diagnostic.h:1110
NestedNameSpecifier.h
LangOptions.h
Diagnostic.h
clang::TemplateArgument
Represents a template argument.
Definition: TemplateBase.h:61
clang::RISCV::Policy
Policy
Definition: RISCVVIntrinsicUtils.h:96
clang::TemplateName::getAsAssumedTemplateName
AssumedTemplateStorage * getAsAssumedTemplateName() const
Retrieve information on a name that has been assumed to be a template-name in order to permit a call ...
Definition: TemplateName.cpp:175
clang::TemplateTemplateParmDecl
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Definition: DeclTemplate.h:1624
clang::TemplateName::Template
@ Template
A single template declaration.
Definition: TemplateName.h:218
clang::TemplateName::getAsUsingShadowDecl
UsingShadowDecl * getAsUsingShadowDecl() const
Retrieve the using shadow declaration through which the underlying template declaration is introduced...
Definition: TemplateName.cpp:209
clang::getOperatorSpelling
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
Definition: IdentifierTable.cpp:818
clang::TemplateName::SubstTemplateTemplateParmPack
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
Definition: TemplateName.h:242
clang::SubstTemplateTemplateParmPackStorage
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:139
clang::operator<<
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
Definition: ASTContext.cpp:13391
clang::TemplateName::isNull
bool isNull() const
Determine whether this template name is NULL.
Definition: TemplateName.cpp:120
clang::TemplateName::TemplateName
TemplateName()=default
clang::UncommonTemplateNameStorage
Implementation class used to describe either a set of overloaded template names or an already-substit...
Definition: TemplateName.h:47
clang::DependentTemplateName
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:489
clang::TemplateName::getKind
NameKind getKind() const
Definition: TemplateName.cpp:122
clang::TemplateName::getAsQualifiedTemplateName
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
Definition: TemplateName.cpp:201
clang::SubstTemplateTemplateParmPackStorage::getParameterPack
TemplateTemplateParmDecl * getParameterPack() const
Retrieve the template template parameter pack being substituted.
Definition: TemplateName.cpp:42
clang::Decl::getPreviousDecl
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
Definition: DeclBase.h:1026
clang::Decl::getFriendObjectKind
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
Definition: DeclBase.h:1185
clang::UncommonTemplateNameStorage::BitsTag::Data
unsigned Data
The pack index, or the number of stored templates or template arguments, depending on which subclass ...
Definition: TemplateName.h:65
clang::TemplateName::QualifiedTemplate
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
Definition: TemplateName.h:229
clang::TemplateName
Represents a C++ template name within the type system.
Definition: TemplateName.h:201
clang::TemplateDecl
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:408
llvm::ArrayRef< TemplateArgument >
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::TemplateName::dump
void dump() const
Debugging aid that dumps the template name to standard error.
Definition: TemplateName.cpp:370
clang::QualifiedTemplateName
Represents a template name that was expressed as a qualified name.
Definition: TemplateName.h:432
LLVM.h
clang::UncommonTemplateNameStorage::getAsSubstTemplateTemplateParmPack
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack()
Definition: TemplateName.h:98
clang::UncommonTemplateNameStorage::BitsTag::Index
unsigned Index
Definition: TemplateName.h:61
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:81
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::TemplateName::SubstTemplateTemplateParm
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
Definition: TemplateName.h:237
clang::TemplateName::print
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
Definition: TemplateName.cpp:285
clang::Builtin::ID
ID
Definition: Builtins.h:52
clang::SubstTemplateTemplateParmStorage
A structure for storing the information associated with a substituted template template parameter.
Definition: TemplateName.h:373
clang
Definition: CalledOnceCheck.h:17
clang::TemplateName::Profile
void Profile(llvm::FoldingSetNodeID &ID)
Definition: TemplateName.h:353
clang::SubstTemplateTemplateParmPackStorage::SubstTemplateTemplateParmPackStorage
SubstTemplateTemplateParmPackStorage(ArrayRef< TemplateArgument > ArgPack, Decl *AssociatedDecl, unsigned Index, bool Final)
Definition: TemplateName.cpp:70
clang::getReplacedTemplateParameterList
TemplateParameterList * getReplacedTemplateParameterList(Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
Definition: DeclTemplate.cpp:1599
clang::TemplateName::AssumedTemplate
@ AssumedTemplate
An unqualified-id that has been assumed to name a function template that will be found by ADL.
Definition: TemplateName.h:225
clang::TemplateName::getAsDependentTemplateName
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
Definition: TemplateName.cpp:205
clang::SubstTemplateTemplateParmPackStorage::Profile
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context)
Definition: TemplateName.cpp:79
clang::SubstTemplateTemplateParmPackStorage::getFinal
bool getFinal() const
Definition: TemplateName.cpp:89
clang::TemplateName::OverloadedTemplate
@ OverloadedTemplate
A set of overloaded template declarations.
Definition: TemplateName.h:221
clang::UncommonTemplateNameStorage::getAsSubstTemplateTemplateParm
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm()
Definition: TemplateName.h:92
clang::TemplateName::Qualified
Qualified
Definition: TemplateName.h:334
clang::SubstTemplateTemplateParmStorage::getAssociatedDecl
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
Definition: TemplateName.h:392
clang::TemplateName::NameKind
NameKind
Definition: TemplateName.h:216
clang::SubstTemplateTemplateParmStorage::Profile
void Profile(llvm::FoldingSetNodeID &ID)
Definition: TemplateName.cpp:55
clang::TemplateName::getAsSubstTemplateTemplateParmPack
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
Definition: TemplateName.cpp:193
clang::AssumedTemplateStorage
A structure for storing the information associated with a name that has been assumed to be a template...
Definition: DeclarationName.h:940
clang::UncommonTemplateNameStorage::Bits
struct BitsTag Bits
Definition: TemplateName.h:69
clang::SubstTemplateTemplateParmPackStorage::getIndex
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
Definition: TemplateName.h:155
clang::Decl::getMostRecentDecl
Decl * getMostRecentDecl()
Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...
Definition: DeclBase.h:1041
clang::TemplateName::DependentTemplate
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
Definition: TemplateName.h:233
clang::TemplateName::UsingTemplate
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
Definition: TemplateName.h:246