1//===- DeclTemplate.h - Classes for representing C++ templates --*- C++ -*-===//
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/// \file
10/// Defines the C++ template declaration subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
15#define LLVM_CLANG_AST_DECLTEMPLATE_H
16
17#include "clang/AST/ASTConcept.h"
18#include "clang/AST/ASTContext.h"
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclBase.h"
21#include "clang/AST/DeclCXX.h"
22#include "clang/AST/DeclFriend.h"
23#include "clang/AST/DeclarationName.h"
24#include "clang/AST/Redeclarable.h"
25#include "clang/AST/TemplateBase.h"
26#include "clang/AST/Type.h"
27#include "clang/Basic/LLVM.h"
28#include "clang/Basic/SourceLocation.h"
29#include "clang/Basic/Specifiers.h"
30#include "clang/Basic/TemplateKinds.h"
31#include "llvm/ADT/ArrayRef.h"
32#include "llvm/ADT/FoldingSet.h"
33#include "llvm/ADT/PointerIntPair.h"
34#include "llvm/ADT/PointerUnion.h"
35#include "llvm/ADT/iterator.h"
36#include "llvm/ADT/iterator_range.h"
37#include "llvm/Support/Casting.h"
38#include "llvm/Support/Compiler.h"
39#include "llvm/Support/TrailingObjects.h"
40#include <cassert>
41#include <cstddef>
42#include <cstdint>
43#include <iterator>
44#include <optional>
45#include <utility>
46
47namespace clang {
48
49enum BuiltinTemplateKind : int;
50class ClassTemplateDecl;
51class ClassTemplatePartialSpecializationDecl;
52class Expr;
53class FunctionTemplateDecl;
54class IdentifierInfo;
55class NonTypeTemplateParmDecl;
56class TemplateDecl;
57class TemplateTemplateParmDecl;
58class TemplateTypeParmDecl;
59class ConceptDecl;
60class UnresolvedSetImpl;
61class VarTemplateDecl;
62class VarTemplatePartialSpecializationDecl;
63
64/// Stores a template parameter of any kind.
65using TemplateParameter =
66 llvm::PointerUnion<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
67 TemplateTemplateParmDecl *>;
68
69NamedDecl *getAsNamedDecl(TemplateParameter P);
70
71/// Stores a list of template parameters for a TemplateDecl and its
72/// derived classes.
73class TemplateParameterList final
74 : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
75 Expr *> {
76 /// The template argument list of the template parameter list.
77 TemplateArgument *InjectedArgs = nullptr;
78
79 /// The location of the 'template' keyword.
80 SourceLocation TemplateLoc;
81
82 /// The locations of the '<' and '>' angle brackets.
83 SourceLocation LAngleLoc, RAngleLoc;
84
85 /// The number of template parameters in this template
86 /// parameter list.
87 unsigned NumParams : 29;
88
89 /// Whether this template parameter list contains an unexpanded parameter
90 /// pack.
91 LLVM_PREFERRED_TYPE(bool)
92 unsigned ContainsUnexpandedParameterPack : 1;
93
94 /// Whether this template parameter list has a requires clause.
95 LLVM_PREFERRED_TYPE(bool)
96 unsigned HasRequiresClause : 1;
97
98 /// Whether any of the template parameters has constrained-parameter
99 /// constraint-expression.
100 LLVM_PREFERRED_TYPE(bool)
101 unsigned HasConstrainedParameters : 1;
102
103protected:
104 TemplateParameterList(const ASTContext& C, SourceLocation TemplateLoc,
105 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
106 SourceLocation RAngleLoc, Expr *RequiresClause);
107
108 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
109 return NumParams;
110 }
111
112 size_t numTrailingObjects(OverloadToken<Expr *>) const {
113 return HasRequiresClause ? 1 : 0;
114 }
115
116public:
117 template <size_t N, bool HasRequiresClause>
118 friend class FixedSizeTemplateParameterListStorage;
119 friend TrailingObjects;
120
121 static TemplateParameterList *Create(const ASTContext &C,
122 SourceLocation TemplateLoc,
123 SourceLocation LAngleLoc,
124 ArrayRef<NamedDecl *> Params,
125 SourceLocation RAngleLoc,
126 Expr *RequiresClause);
127
128 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
129
130 /// Iterates through the template parameters in this list.
131 using iterator = NamedDecl **;
132
133 /// Iterates through the template parameters in this list.
134 using const_iterator = NamedDecl * const *;
135
136 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
137 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
138 iterator end() { return begin() + NumParams; }
139 const_iterator end() const { return begin() + NumParams; }
140
141 unsigned size() const { return NumParams; }
142 bool empty() const { return NumParams == 0; }
143
144 ArrayRef<NamedDecl *> asArray() { return {begin(), end()}; }
145 ArrayRef<const NamedDecl *> asArray() const { return {begin(), size()}; }
146
147 NamedDecl* getParam(unsigned Idx) {
148 assert(Idx < size() && "Template parameter index out-of-range");
149 return begin()[Idx];
150 }
151 const NamedDecl* getParam(unsigned Idx) const {
152 assert(Idx < size() && "Template parameter index out-of-range");
153 return begin()[Idx];
154 }
155
156 /// Returns the minimum number of arguments needed to form a
157 /// template specialization.
158 ///
159 /// This may be fewer than the number of template parameters, if some of
160 /// the parameters have default arguments or if there is a parameter pack.
161 unsigned getMinRequiredArguments() const;
162
163 /// Get the depth of this template parameter list in the set of
164 /// template parameter lists.
165 ///
166 /// The first template parameter list in a declaration will have depth 0,
167 /// the second template parameter list will have depth 1, etc.
168 unsigned getDepth() const;
169
170 /// Determine whether this template parameter list contains an
171 /// unexpanded parameter pack.
172 bool containsUnexpandedParameterPack() const;
173
174 /// Determine whether this template parameter list contains a parameter pack.
175 bool hasParameterPack() const {
176 for (const NamedDecl *P : asArray())
177 if (P->isParameterPack())
178 return true;
179 return false;
180 }
181
182 /// The constraint-expression of the associated requires-clause.
183 Expr *getRequiresClause() {
184 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
185 }
186
187 /// The constraint-expression of the associated requires-clause.
188 const Expr *getRequiresClause() const {
189 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
190 }
191
192 /// \brief All associated constraints derived from this template parameter
193 /// list, including the requires clause and any constraints derived from
194 /// constrained-parameters.
195 ///
196 /// The constraints in the resulting list are to be treated as if in a
197 /// conjunction ("and").
198 void getAssociatedConstraints(
199 llvm::SmallVectorImpl<AssociatedConstraint> &AC) const;
200
201 bool hasAssociatedConstraints() const;
202
203 /// Get the template argument list of the template parameter list.
204 ArrayRef<TemplateArgument> getInjectedTemplateArgs(const ASTContext &Context);
205
206 SourceLocation getTemplateLoc() const { return TemplateLoc; }
207 SourceLocation getLAngleLoc() const { return LAngleLoc; }
208 SourceLocation getRAngleLoc() const { return RAngleLoc; }
209
210 SourceRange getSourceRange() const LLVM_READONLY {
211 return SourceRange(TemplateLoc, RAngleLoc);
212 }
213
214 void print(raw_ostream &Out, const ASTContext &Context,
215 bool OmitTemplateKW = false) const;
216 void print(raw_ostream &Out, const ASTContext &Context,
217 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
218
219 static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy,
220 const TemplateParameterList *TPL,
221 unsigned Idx);
222};
223
224/// Stores a list of template parameters and the associated
225/// requires-clause (if any) for a TemplateDecl and its derived classes.
226/// Suitable for creating on the stack.
227template <size_t N, bool HasRequiresClause>
228class FixedSizeTemplateParameterListStorage
229 : public TemplateParameterList::FixedSizeStorageOwner {
230 typename TemplateParameterList::FixedSizeStorage<
231 NamedDecl *, Expr *>::with_counts<
232 N, HasRequiresClause ? 1u : 0u
233 >::type storage;
234
235public:
236 FixedSizeTemplateParameterListStorage(const ASTContext &C,
237 SourceLocation TemplateLoc,
238 SourceLocation LAngleLoc,
239 ArrayRef<NamedDecl *> Params,
240 SourceLocation RAngleLoc,
241 Expr *RequiresClause)
242 : FixedSizeStorageOwner(
243 (assert(N == Params.size()),
244 assert(HasRequiresClause == (RequiresClause != nullptr)),
245 new (static_cast<void *>(&storage)) TemplateParameterList(C,
246 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
247};
248
249/// A template argument list.
250class TemplateArgumentList final
251 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
252 /// The number of template arguments in this template
253 /// argument list.
254 unsigned NumArguments;
255
256 // Constructs an instance with an internal Argument list, containing
257 // a copy of the Args array. (Called by CreateCopy)
258 TemplateArgumentList(ArrayRef<TemplateArgument> Args);
259
260public:
261 friend TrailingObjects;
262
263 TemplateArgumentList(const TemplateArgumentList &) = delete;
264 TemplateArgumentList &operator=(const TemplateArgumentList &) = delete;
265
266 /// Create a new template argument list that copies the given set of
267 /// template arguments.
268 static TemplateArgumentList *CreateCopy(ASTContext &Context,
269 ArrayRef<TemplateArgument> Args);
270
271 /// Retrieve the template argument at a given index.
272 const TemplateArgument &get(unsigned Idx) const {
273 assert(Idx < NumArguments && "Invalid template argument index");
274 return data()[Idx];
275 }
276
277 /// Retrieve the template argument at a given index.
278 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
279
280 /// Produce this as an array ref.
281 ArrayRef<TemplateArgument> asArray() const {
282 return getTrailingObjects(N: size());
283 }
284
285 /// Retrieve the number of template arguments in this
286 /// template argument list.
287 unsigned size() const { return NumArguments; }
288
289 /// Retrieve a pointer to the template argument list.
290 const TemplateArgument *data() const { return getTrailingObjects(); }
291};
292
293void *allocateDefaultArgStorageChain(const ASTContext &C);
294
295/// Storage for a default argument. This is conceptually either empty, or an
296/// argument value, or a pointer to a previous declaration that had a default
297/// argument.
298///
299/// However, this is complicated by modules: while we require all the default
300/// arguments for a template to be equivalent, there may be more than one, and
301/// we need to track all the originating parameters to determine if the default
302/// argument is visible.
303template<typename ParmDecl, typename ArgType>
304class DefaultArgStorage {
305 /// Storage for both the value *and* another parameter from which we inherit
306 /// the default argument. This is used when multiple default arguments for a
307 /// parameter are merged together from different modules.
308 struct Chain {
309 ParmDecl *PrevDeclWithDefaultArg;
310 ArgType Value;
311 };
312 static_assert(sizeof(Chain) == sizeof(void *) * 2,
313 "non-pointer argument type?");
314
315 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
316
317 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
318 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
319 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
320 Parm = Prev;
321 assert(!isa<ParmDecl *>(Parm->getDefaultArgStorage().ValueOrInherited) &&
322 "should only be one level of indirection");
323 return Parm;
324 }
325
326public:
327 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
328
329 /// Determine whether there is a default argument for this parameter.
330 bool isSet() const { return !ValueOrInherited.isNull(); }
331
332 /// Determine whether the default argument for this parameter was inherited
333 /// from a previous declaration of the same entity.
334 bool isInherited() const { return isa<ParmDecl *>(ValueOrInherited); }
335
336 /// Get the default argument's value. This does not consider whether the
337 /// default argument is visible.
338 ArgType get() const {
339 const DefaultArgStorage *Storage = this;
340 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
341 Storage = &Prev->getDefaultArgStorage();
342 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
343 return C->Value;
344 return cast<ArgType>(Storage->ValueOrInherited);
345 }
346
347 /// Get the parameter from which we inherit the default argument, if any.
348 /// This is the parameter on which the default argument was actually written.
349 const ParmDecl *getInheritedFrom() const {
350 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
351 return D;
352 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
353 return C->PrevDeclWithDefaultArg;
354 return nullptr;
355 }
356
357 /// Set the default argument.
358 void set(ArgType Arg) {
359 assert(!isSet() && "default argument already set");
360 ValueOrInherited = Arg;
361 }
362
363 /// Set that the default argument was inherited from another parameter.
364 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
365 InheritedFrom = getParmOwningDefaultArg(Parm: InheritedFrom);
366 if (!isSet())
367 ValueOrInherited = InheritedFrom;
368 else if ([[maybe_unused]] auto *D =
369 dyn_cast<ParmDecl *>(ValueOrInherited)) {
370 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
371 ValueOrInherited =
372 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
373 } else if (auto *Inherited = dyn_cast<Chain *>(ValueOrInherited)) {
374 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
375 InheritedFrom));
376 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
377 } else
378 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
379 Chain{InheritedFrom, cast<ArgType>(ValueOrInherited)};
380 }
381
382 /// Remove the default argument, even if it was inherited.
383 void clear() {
384 ValueOrInherited = ArgType();
385 }
386};
387
388//===----------------------------------------------------------------------===//
389// Kinds of Templates
390//===----------------------------------------------------------------------===//
391
392/// \brief The base class of all kinds of template declarations (e.g.,
393/// class, function, etc.).
394///
395/// The TemplateDecl class stores the list of template parameters and a
396/// reference to the templated scoped declaration: the underlying AST node.
397class TemplateDecl : public NamedDecl {
398 void anchor() override;
399
400protected:
401 // Construct a template decl with name, parameters, and templated element.
402 TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
403 TemplateParameterList *Params, NamedDecl *Decl);
404
405 // Construct a template decl with the given name and parameters.
406 // Used when there is no templated element (e.g., for tt-params).
407 TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
408 TemplateParameterList *Params)
409 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
410
411public:
412 friend class ASTDeclReader;
413 friend class ASTDeclWriter;
414
415 /// Get the list of template parameters
416 TemplateParameterList *getTemplateParameters() const {
417 return TemplateParams;
418 }
419
420 /// \brief Get the total constraint-expression associated with this template,
421 /// including constraint-expressions derived from the requires-clause,
422 /// trailing requires-clause (for functions and methods) and constrained
423 /// template parameters.
424 void getAssociatedConstraints(
425 llvm::SmallVectorImpl<AssociatedConstraint> &AC) const;
426
427 bool hasAssociatedConstraints() const;
428
429 /// Get the underlying, templated declaration.
430 NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
431
432 // Should a specialization behave like an alias for another type.
433 bool isTypeAlias() const;
434
435 // Implement isa/cast/dyncast/etc.
436 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
437
438 static bool classofKind(Kind K) {
439 return K >= firstTemplate && K <= lastTemplate;
440 }
441
442 SourceRange getSourceRange() const override LLVM_READONLY {
443 return SourceRange(getTemplateParameters()->getTemplateLoc(),
444 TemplatedDecl->getSourceRange().getEnd());
445 }
446
447protected:
448 NamedDecl *TemplatedDecl;
449 TemplateParameterList *TemplateParams;
450
451public:
452 void setTemplateParameters(TemplateParameterList *TParams) {
453 TemplateParams = TParams;
454 }
455
456 /// Initialize the underlying templated declaration.
457 void init(NamedDecl *NewTemplatedDecl) {
458 if (TemplatedDecl)
459 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
460 else
461 TemplatedDecl = NewTemplatedDecl;
462 }
463};
464
465/// Provides information about a function template specialization,
466/// which is a FunctionDecl that has been explicitly specialization or
467/// instantiated from a function template.
468class FunctionTemplateSpecializationInfo final
469 : public llvm::FoldingSetNode,
470 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
471 MemberSpecializationInfo *> {
472 /// The function template specialization that this structure describes and a
473 /// flag indicating if the function is a member specialization.
474 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
475
476 /// The function template from which this function template
477 /// specialization was generated.
478 ///
479 /// The two bits contain the top 4 values of TemplateSpecializationKind.
480 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
481
482public:
483 /// The template arguments used to produce the function template
484 /// specialization from the function template.
485 TemplateArgumentList *TemplateArguments;
486
487 /// The template arguments as written in the sources, if provided.
488 /// FIXME: Normally null; tail-allocate this.
489 const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
490
491 /// The point at which this function template specialization was
492 /// first instantiated.
493 SourceLocation PointOfInstantiation;
494
495private:
496 FunctionTemplateSpecializationInfo(
497 FunctionDecl *FD, FunctionTemplateDecl *Template,
498 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,
499 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
500 SourceLocation POI, MemberSpecializationInfo *MSInfo)
501 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
502 TemplateArguments(TemplateArgs),
503 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
504 PointOfInstantiation(POI) {
505 if (MSInfo)
506 getTrailingObjects()[0] = MSInfo;
507 }
508
509 size_t numTrailingObjects() const { return Function.getInt(); }
510
511public:
512 friend TrailingObjects;
513
514 static FunctionTemplateSpecializationInfo *
515 Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
516 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,
517 const TemplateArgumentListInfo *TemplateArgsAsWritten,
518 SourceLocation POI, MemberSpecializationInfo *MSInfo);
519
520 /// Retrieve the declaration of the function template specialization.
521 FunctionDecl *getFunction() const { return Function.getPointer(); }
522
523 /// Retrieve the template from which this function was specialized.
524 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
525
526 /// Determine what kind of template specialization this is.
527 TemplateSpecializationKind getTemplateSpecializationKind() const {
528 return (TemplateSpecializationKind)(Template.getInt() + 1);
529 }
530
531 bool isExplicitSpecialization() const {
532 return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
533 }
534
535 /// True if this declaration is an explicit specialization,
536 /// explicit instantiation declaration, or explicit instantiation
537 /// definition.
538 bool isExplicitInstantiationOrSpecialization() const {
539 return isTemplateExplicitInstantiationOrSpecialization(
540 Kind: getTemplateSpecializationKind());
541 }
542
543 /// Set the template specialization kind.
544 void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
545 assert(TSK != TSK_Undeclared &&
546 "Cannot encode TSK_Undeclared for a function template specialization");
547 Template.setInt(TSK - 1);
548 }
549
550 /// Retrieve the first point of instantiation of this function
551 /// template specialization.
552 ///
553 /// The point of instantiation may be an invalid source location if this
554 /// function has yet to be instantiated.
555 SourceLocation getPointOfInstantiation() const {
556 return PointOfInstantiation;
557 }
558
559 /// Set the (first) point of instantiation of this function template
560 /// specialization.
561 void setPointOfInstantiation(SourceLocation POI) {
562 PointOfInstantiation = POI;
563 }
564
565 /// Get the specialization info if this function template specialization is
566 /// also a member specialization:
567 ///
568 /// \code
569 /// template<typename> struct A {
570 /// template<typename> void f();
571 /// template<> void f<int>();
572 /// };
573 /// \endcode
574 ///
575 /// Here, A<int>::f<int> is a function template specialization that is
576 /// an explicit specialization of A<int>::f, but it's also a member
577 /// specialization (an implicit instantiation in this case) of A::f<int>.
578 /// Further:
579 ///
580 /// \code
581 /// template<> template<> void A<int>::f<int>() {}
582 /// \endcode
583 ///
584 /// ... declares a function template specialization that is an explicit
585 /// specialization of A<int>::f, and is also an explicit member
586 /// specialization of A::f<int>.
587 ///
588 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
589 /// need not be the same as that returned by getTemplateSpecializationKind(),
590 /// and represents the relationship between the function and the class-scope
591 /// explicit specialization in the original templated class -- whereas our
592 /// TemplateSpecializationKind represents the relationship between the
593 /// function and the function template, and should always be
594 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
595 MemberSpecializationInfo *getMemberSpecializationInfo() const {
596 return numTrailingObjects() ? getTrailingObjects()[0] : nullptr;
597 }
598
599 void Profile(llvm::FoldingSetNodeID &ID) {
600 Profile(ID, TemplateArgs: TemplateArguments->asArray(), Context: getFunction()->getASTContext());
601 }
602
603 static void
604 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
605 const ASTContext &Context) {
606 ID.AddInteger(I: TemplateArgs.size());
607 for (const TemplateArgument &TemplateArg : TemplateArgs)
608 TemplateArg.Profile(ID, Context);
609 }
610};
611
612/// Provides information a specialization of a member of a class
613/// template, which may be a member function, static data member,
614/// member class or member enumeration.
615class MemberSpecializationInfo {
616 // The member declaration from which this member was instantiated, and the
617 // manner in which the instantiation occurred (in the lower two bits).
618 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
619
620 // The point at which this member was first instantiated.
621 SourceLocation PointOfInstantiation;
622
623public:
624 explicit
625 MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
626 SourceLocation POI = SourceLocation())
627 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
628 assert(TSK != TSK_Undeclared &&
629 "Cannot encode undeclared template specializations for members");
630 }
631
632 /// Retrieve the member declaration from which this member was
633 /// instantiated.
634 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
635
636 /// Determine what kind of template specialization this is.
637 TemplateSpecializationKind getTemplateSpecializationKind() const {
638 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
639 }
640
641 bool isExplicitSpecialization() const {
642 return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
643 }
644
645 /// Set the template specialization kind.
646 void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
647 assert(TSK != TSK_Undeclared &&
648 "Cannot encode undeclared template specializations for members");
649 MemberAndTSK.setInt(TSK - 1);
650 }
651
652 /// Retrieve the first point of instantiation of this member.
653 /// If the point of instantiation is an invalid location, then this member
654 /// has not yet been instantiated.
655 SourceLocation getPointOfInstantiation() const {
656 return PointOfInstantiation;
657 }
658
659 /// Set the first point of instantiation.
660 void setPointOfInstantiation(SourceLocation POI) {
661 PointOfInstantiation = POI;
662 }
663};
664
665/// Provides information about a dependent function-template
666/// specialization declaration.
667///
668/// This is used for function templates explicit specializations declared
669/// within class templates:
670///
671/// \code
672/// template<typename> struct A {
673/// template<typename> void f();
674/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
675/// };
676/// \endcode
677///
678/// As well as dependent friend declarations naming function template
679/// specializations declared within class templates:
680///
681/// \code
682/// template \<class T> void foo(T);
683/// template \<class T> class A {
684/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
685/// };
686/// \endcode
687class DependentFunctionTemplateSpecializationInfo final
688 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
689 FunctionTemplateDecl *> {
690 friend TrailingObjects;
691
692 /// The number of candidates for the primary template.
693 unsigned NumCandidates;
694
695 DependentFunctionTemplateSpecializationInfo(
696 const UnresolvedSetImpl &Candidates,
697 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
698
699public:
700 /// The template arguments as written in the sources, if provided.
701 const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
702
703 static DependentFunctionTemplateSpecializationInfo *
704 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
705 const TemplateArgumentListInfo *TemplateArgs);
706
707 /// Returns the candidates for the primary function template.
708 ArrayRef<FunctionTemplateDecl *> getCandidates() const {
709 return getTrailingObjects(N: NumCandidates);
710 }
711};
712
713/// Declaration of a redeclarable template.
714class RedeclarableTemplateDecl : public TemplateDecl,
715 public Redeclarable<RedeclarableTemplateDecl>
716{
717 using redeclarable_base = Redeclarable<RedeclarableTemplateDecl>;
718
719 RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
720 return getNextRedeclaration();
721 }
722
723 RedeclarableTemplateDecl *getPreviousDeclImpl() override {
724 return getPreviousDecl();
725 }
726
727 RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
728 return getMostRecentDecl();
729 }
730
731 void anchor() override;
732
733protected:
734 template <typename EntryType> struct SpecEntryTraits {
735 using DeclType = EntryType;
736
737 static DeclType *getDecl(EntryType *D) {
738 return D;
739 }
740
741 static ArrayRef<TemplateArgument> getTemplateArgs(EntryType *D) {
742 return D->getTemplateArgs().asArray();
743 }
744 };
745
746 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
747 typename DeclType = typename SETraits::DeclType>
748 struct SpecIterator
749 : llvm::iterator_adaptor_base<
750 SpecIterator<EntryType, SETraits, DeclType>,
751 typename llvm::FoldingSetVector<EntryType>::iterator,
752 typename std::iterator_traits<typename llvm::FoldingSetVector<
753 EntryType>::iterator>::iterator_category,
754 DeclType *, ptrdiff_t, DeclType *, DeclType *> {
755 SpecIterator() = default;
756 explicit SpecIterator(
757 typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
758 : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
759
760 DeclType *operator*() const {
761 return SETraits::getDecl(&*this->I)->getMostRecentDecl();
762 }
763
764 DeclType *operator->() const { return **this; }
765 };
766
767 template <typename EntryType>
768 static SpecIterator<EntryType>
769 makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
770 return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
771 }
772
773 void loadLazySpecializationsImpl(bool OnlyPartial = false) const;
774
775 bool loadLazySpecializationsImpl(ArrayRef<TemplateArgument> Args,
776 TemplateParameterList *TPL = nullptr) const;
777
778 template <class EntryType, typename... ProfileArguments>
779 typename SpecEntryTraits<EntryType>::DeclType *
780 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
781 void *&InsertPos, ProfileArguments... ProfileArgs);
782
783 template <class EntryType, typename... ProfileArguments>
784 typename SpecEntryTraits<EntryType>::DeclType *
785 findSpecializationLocally(llvm::FoldingSetVector<EntryType> &Specs,
786 void *&InsertPos, ProfileArguments... ProfileArgs);
787
788 template <class Derived, class EntryType>
789 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
790 EntryType *Entry, void *InsertPos);
791
792 struct CommonBase {
793 CommonBase() : InstantiatedFromMember(nullptr, false) {}
794
795 /// The template from which this was most
796 /// directly instantiated (or null).
797 ///
798 /// The boolean value indicates whether this template
799 /// was explicitly specialized.
800 llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
801 InstantiatedFromMember;
802 };
803
804 /// Pointer to the common data shared by all declarations of this
805 /// template.
806 mutable CommonBase *Common = nullptr;
807
808 /// Retrieves the "common" pointer shared by all (re-)declarations of
809 /// the same template. Calling this routine may implicitly allocate memory
810 /// for the common pointer.
811 CommonBase *getCommonPtr() const;
812
813 virtual CommonBase *newCommon(ASTContext &C) const = 0;
814
815 // Construct a template decl with name, parameters, and templated element.
816 RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
817 SourceLocation L, DeclarationName Name,
818 TemplateParameterList *Params, NamedDecl *Decl)
819 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
820
821public:
822 friend class ASTDeclReader;
823 friend class ASTDeclWriter;
824 friend class ASTReader;
825 template <class decl_type> friend class RedeclarableTemplate;
826
827 /// Retrieves the canonical declaration of this template.
828 RedeclarableTemplateDecl *getCanonicalDecl() override {
829 return getFirstDecl();
830 }
831 const RedeclarableTemplateDecl *getCanonicalDecl() const {
832 return getFirstDecl();
833 }
834
835 /// Determines whether this template was a specialization of a
836 /// member template.
837 ///
838 /// In the following example, the function template \c X<int>::f and the
839 /// member template \c X<int>::Inner are member specializations.
840 ///
841 /// \code
842 /// template<typename T>
843 /// struct X {
844 /// template<typename U> void f(T, U);
845 /// template<typename U> struct Inner;
846 /// };
847 ///
848 /// template<> template<typename T>
849 /// void X<int>::f(int, T);
850 /// template<> template<typename T>
851 /// struct X<int>::Inner { /* ... */ };
852 /// \endcode
853 bool isMemberSpecialization() const {
854 return getCommonPtr()->InstantiatedFromMember.getInt();
855 }
856
857 /// Note that this member template is a specialization.
858 void setMemberSpecialization() {
859 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
860 "Only member templates can be member template specializations");
861 getCommonPtr()->InstantiatedFromMember.setInt(true);
862 }
863
864 /// Retrieve the member template from which this template was
865 /// instantiated, or nullptr if this template was not instantiated from a
866 /// member template.
867 ///
868 /// A template is instantiated from a member template when the member
869 /// template itself is part of a class template (or member thereof). For
870 /// example, given
871 ///
872 /// \code
873 /// template<typename T>
874 /// struct X {
875 /// template<typename U> void f(T, U);
876 /// };
877 ///
878 /// void test(X<int> x) {
879 /// x.f(1, 'a');
880 /// };
881 /// \endcode
882 ///
883 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
884 /// template
885 ///
886 /// \code
887 /// template<typename U> void X<int>::f(int, U);
888 /// \endcode
889 ///
890 /// which was itself created during the instantiation of \c X<int>. Calling
891 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
892 /// retrieve the FunctionTemplateDecl for the original template \c f within
893 /// the class template \c X<T>, i.e.,
894 ///
895 /// \code
896 /// template<typename T>
897 /// template<typename U>
898 /// void X<T>::f(T, U);
899 /// \endcode
900 RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
901 return getCommonPtr()->InstantiatedFromMember.getPointer();
902 }
903
904 void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
905 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
906 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
907 }
908
909 /// Retrieve the "injected" template arguments that correspond to the
910 /// template parameters of this template.
911 ///
912 /// Although the C++ standard has no notion of the "injected" template
913 /// arguments for a template, the notion is convenient when
914 /// we need to perform substitutions inside the definition of a template.
915 ArrayRef<TemplateArgument>
916 getInjectedTemplateArgs(const ASTContext &Context) const {
917 return getTemplateParameters()->getInjectedTemplateArgs(Context);
918 }
919
920 using redecl_range = redeclarable_base::redecl_range;
921 using redecl_iterator = redeclarable_base::redecl_iterator;
922
923 using redeclarable_base::redecls_begin;
924 using redeclarable_base::redecls_end;
925 using redeclarable_base::redecls;
926 using redeclarable_base::getPreviousDecl;
927 using redeclarable_base::getMostRecentDecl;
928 using redeclarable_base::isFirstDecl;
929
930 // Implement isa/cast/dyncast/etc.
931 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
932
933 static bool classofKind(Kind K) {
934 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
935 }
936};
937
938template <> struct RedeclarableTemplateDecl::
939SpecEntryTraits<FunctionTemplateSpecializationInfo> {
940 using DeclType = FunctionDecl;
941
942 static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) {
943 return I->getFunction();
944 }
945
946 static ArrayRef<TemplateArgument>
947 getTemplateArgs(FunctionTemplateSpecializationInfo *I) {
948 return I->TemplateArguments->asArray();
949 }
950};
951
952/// Declaration of a template function.
953class FunctionTemplateDecl : public RedeclarableTemplateDecl {
954protected:
955 friend class FunctionDecl;
956
957 /// Data that is common to all of the declarations of a given
958 /// function template.
959 struct Common : CommonBase {
960 /// The function template specializations for this function
961 /// template, including explicit specializations and instantiations.
962 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
963
964 Common() = default;
965 };
966
967 FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
968 DeclarationName Name, TemplateParameterList *Params,
969 NamedDecl *Decl)
970 : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
971 Decl) {}
972
973 CommonBase *newCommon(ASTContext &C) const override;
974
975 Common *getCommonPtr() const {
976 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
977 }
978
979 /// Retrieve the set of function template specializations of this
980 /// function template.
981 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
982 getSpecializations() const;
983
984 /// Add a specialization of this function template.
985 ///
986 /// \param InsertPos Insert position in the FoldingSetVector, must have been
987 /// retrieved by an earlier call to findSpecialization().
988 void addSpecialization(FunctionTemplateSpecializationInfo* Info,
989 void *InsertPos);
990
991public:
992 friend class ASTDeclReader;
993 friend class ASTDeclWriter;
994
995 /// Load any lazily-loaded specializations from the external source.
996 void LoadLazySpecializations() const;
997
998 /// Get the underlying function declaration of the template.
999 FunctionDecl *getTemplatedDecl() const {
1000 return static_cast<FunctionDecl *>(TemplatedDecl);
1001 }
1002
1003 /// Returns whether this template declaration defines the primary
1004 /// pattern.
1005 bool isThisDeclarationADefinition() const {
1006 return getTemplatedDecl()->isThisDeclarationADefinition();
1007 }
1008
1009 bool isCompatibleWithDefinition() const {
1010 return getTemplatedDecl()->isInstantiatedFromMemberTemplate() ||
1011 isThisDeclarationADefinition();
1012 }
1013
1014 // This bit closely tracks 'RedeclarableTemplateDecl::InstantiatedFromMember',
1015 // except this is per declaration, while the redeclarable field is
1016 // per chain. This indicates a template redeclaration which
1017 // is compatible with the definition, in the non-trivial case
1018 // where this is not already a definition.
1019 // This is only really needed for instantiating the definition of friend
1020 // function templates, which can have redeclarations in different template
1021 // contexts.
1022 // The bit is actually stored in the FunctionDecl for space efficiency
1023 // reasons.
1024 void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *D) {
1025 getTemplatedDecl()->setInstantiatedFromMemberTemplate();
1026 RedeclarableTemplateDecl::setInstantiatedFromMemberTemplate(D);
1027 }
1028
1029 /// Return the specialization with the provided arguments if it exists,
1030 /// otherwise return the insertion point.
1031 FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
1032 void *&InsertPos);
1033
1034 FunctionTemplateDecl *getCanonicalDecl() override {
1035 return cast<FunctionTemplateDecl>(
1036 Val: RedeclarableTemplateDecl::getCanonicalDecl());
1037 }
1038 const FunctionTemplateDecl *getCanonicalDecl() const {
1039 return cast<FunctionTemplateDecl>(
1040 Val: RedeclarableTemplateDecl::getCanonicalDecl());
1041 }
1042
1043 /// Retrieve the previous declaration of this function template, or
1044 /// nullptr if no such declaration exists.
1045 FunctionTemplateDecl *getPreviousDecl() {
1046 return cast_or_null<FunctionTemplateDecl>(
1047 Val: static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1048 }
1049 const FunctionTemplateDecl *getPreviousDecl() const {
1050 return cast_or_null<FunctionTemplateDecl>(
1051 Val: static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1052 }
1053
1054 FunctionTemplateDecl *getMostRecentDecl() {
1055 return cast<FunctionTemplateDecl>(
1056 Val: static_cast<RedeclarableTemplateDecl *>(this)
1057 ->getMostRecentDecl());
1058 }
1059 const FunctionTemplateDecl *getMostRecentDecl() const {
1060 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1061 }
1062
1063 FunctionTemplateDecl *getInstantiatedFromMemberTemplate() const {
1064 return cast_or_null<FunctionTemplateDecl>(
1065 Val: RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
1066 }
1067
1068 using spec_iterator = SpecIterator<FunctionTemplateSpecializationInfo>;
1069 using spec_range = llvm::iterator_range<spec_iterator>;
1070
1071 spec_range specializations() const {
1072 return spec_range(spec_begin(), spec_end());
1073 }
1074
1075 spec_iterator spec_begin() const {
1076 return makeSpecIterator(Specs&: getSpecializations(), isEnd: false);
1077 }
1078
1079 spec_iterator spec_end() const {
1080 return makeSpecIterator(Specs&: getSpecializations(), isEnd: true);
1081 }
1082
1083 /// Return whether this function template is an abbreviated function template,
1084 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1085 bool isAbbreviated() const {
1086 // Since the invented template parameters generated from 'auto' parameters
1087 // are either appended to the end of the explicit template parameter list or
1088 // form a new template parameter list, we can simply observe the last
1089 // parameter to determine if such a thing happened.
1090 const TemplateParameterList *TPL = getTemplateParameters();
1091 return TPL->getParam(Idx: TPL->size() - 1)->isImplicit();
1092 }
1093
1094 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1095 void mergePrevDecl(FunctionTemplateDecl *Prev);
1096
1097 /// Create a function template node.
1098 static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
1099 SourceLocation L,
1100 DeclarationName Name,
1101 TemplateParameterList *Params,
1102 NamedDecl *Decl);
1103
1104 /// Create an empty function template node.
1105 static FunctionTemplateDecl *CreateDeserialized(ASTContext &C,
1106 GlobalDeclID ID);
1107
1108 // Implement isa/cast/dyncast support
1109 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
1110 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1111};
1112
1113//===----------------------------------------------------------------------===//
1114// Kinds of Template Parameters
1115//===----------------------------------------------------------------------===//
1116
1117/// Defines the position of a template parameter within a template
1118/// parameter list.
1119///
1120/// Because template parameter can be listed
1121/// sequentially for out-of-line template members, each template parameter is
1122/// given a Depth - the nesting of template parameter scopes - and a Position -
1123/// the occurrence within the parameter list.
1124/// This class is inheritedly privately by different kinds of template
1125/// parameters and is not part of the Decl hierarchy. Just a facility.
1126class TemplateParmPosition {
1127protected:
1128 enum { DepthWidth = 20, PositionWidth = 12 };
1129 unsigned Depth : DepthWidth;
1130 unsigned Position : PositionWidth;
1131
1132 TemplateParmPosition(int D, int P) {
1133 setDepth(D);
1134 setPosition(P);
1135 }
1136
1137public:
1138 TemplateParmPosition() = delete;
1139
1140 /// Get the nesting depth of the template parameter.
1141 unsigned getDepth() const { return Depth; }
1142 void setDepth(int D) {
1143 assert(D >= 0 && "The depth cannot be negative");
1144 assert(D < (1 << DepthWidth) && "The depth is too large");
1145 Depth = D;
1146 }
1147
1148 /// Get the position of the template parameter within its parameter list.
1149 unsigned getPosition() const { return Position; }
1150 void setPosition(int P) {
1151 assert(P >= 0 && "The position cannot be negative");
1152 assert(P < (1 << PositionWidth) && "The position is too large");
1153 Position = P;
1154 }
1155
1156 /// Get the index of the template parameter within its parameter list.
1157 unsigned getIndex() const { return Position; }
1158};
1159
1160/// Declaration of a template type parameter.
1161///
1162/// For example, "T" in
1163/// \code
1164/// template<typename T> class vector;
1165/// \endcode
1166class TemplateTypeParmDecl final : public TypeDecl,
1167 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1168 /// Sema creates these on the stack during auto type deduction.
1169 friend class Sema;
1170 friend TrailingObjects;
1171 friend class ASTDeclReader;
1172
1173 /// Whether this template type parameter was declaration with
1174 /// the 'typename' keyword.
1175 ///
1176 /// If false, it was declared with the 'class' keyword.
1177 bool Typename : 1;
1178
1179 /// Whether this template type parameter has a type-constraint construct.
1180 bool HasTypeConstraint : 1;
1181
1182 /// Whether the type constraint has been initialized. This can be false if the
1183 /// constraint was not initialized yet or if there was an error forming the
1184 /// type constraint.
1185 bool TypeConstraintInitialized : 1;
1186
1187 /// The number of type parameters in an expanded parameter pack, if any.
1188 UnsignedOrNone NumExpanded = std::nullopt;
1189
1190 /// The default template argument, if any.
1191 using DefArgStorage =
1192 DefaultArgStorage<TemplateTypeParmDecl, TemplateArgumentLoc *>;
1193 DefArgStorage DefaultArgument;
1194
1195 TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
1196 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1197 bool HasTypeConstraint, UnsignedOrNone NumExpanded)
1198 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1199 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1200 NumExpanded(NumExpanded) {}
1201
1202public:
1203 static TemplateTypeParmDecl *
1204 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1205 SourceLocation NameLoc, int D, int P, IdentifierInfo *Id,
1206 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1207 UnsignedOrNone NumExpanded = std::nullopt);
1208 static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
1209 GlobalDeclID ID);
1210 static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
1211 GlobalDeclID ID,
1212 bool HasTypeConstraint);
1213
1214 /// Whether this template type parameter was declared with
1215 /// the 'typename' keyword.
1216 ///
1217 /// If not, it was either declared with the 'class' keyword or with a
1218 /// type-constraint (see hasTypeConstraint()).
1219 bool wasDeclaredWithTypename() const {
1220 return Typename && !HasTypeConstraint;
1221 }
1222
1223 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1224
1225 /// Determine whether this template parameter has a default
1226 /// argument.
1227 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1228
1229 /// Retrieve the default argument, if any.
1230 const TemplateArgumentLoc &getDefaultArgument() const {
1231 static const TemplateArgumentLoc NoneLoc;
1232 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1233 }
1234
1235 /// Retrieves the location of the default argument declaration.
1236 SourceLocation getDefaultArgumentLoc() const;
1237
1238 /// Determines whether the default argument was inherited
1239 /// from a previous declaration of this template.
1240 bool defaultArgumentWasInherited() const {
1241 return DefaultArgument.isInherited();
1242 }
1243
1244 /// Set the default argument for this template parameter.
1245 void setDefaultArgument(const ASTContext &C,
1246 const TemplateArgumentLoc &DefArg);
1247
1248 /// Set that this default argument was inherited from another
1249 /// parameter.
1250 void setInheritedDefaultArgument(const ASTContext &C,
1251 TemplateTypeParmDecl *Prev) {
1252 DefaultArgument.setInherited(C, InheritedFrom: Prev);
1253 }
1254
1255 /// Removes the default argument of this template parameter.
1256 void removeDefaultArgument() {
1257 DefaultArgument.clear();
1258 }
1259
1260 /// Set whether this template type parameter was declared with
1261 /// the 'typename' or 'class' keyword.
1262 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1263
1264 /// Retrieve the depth of the template parameter.
1265 unsigned getDepth() const;
1266
1267 /// Retrieve the index of the template parameter.
1268 unsigned getIndex() const;
1269
1270 /// Returns whether this is a parameter pack.
1271 bool isParameterPack() const;
1272
1273 /// Whether this parameter pack is a pack expansion.
1274 ///
1275 /// A template type template parameter pack can be a pack expansion if its
1276 /// type-constraint contains an unexpanded parameter pack.
1277 bool isPackExpansion() const {
1278 if (!isParameterPack())
1279 return false;
1280 if (const TypeConstraint *TC = getTypeConstraint())
1281 if (TC->hasExplicitTemplateArgs())
1282 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1283 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1284 return true;
1285 return false;
1286 }
1287
1288 /// Whether this parameter is a template type parameter pack that has a known
1289 /// list of different type-constraints at different positions.
1290 ///
1291 /// A parameter pack is an expanded parameter pack when the original
1292 /// parameter pack's type-constraint was itself a pack expansion, and that
1293 /// expansion has already been expanded. For example, given:
1294 ///
1295 /// \code
1296 /// template<typename ...Types>
1297 /// struct X {
1298 /// template<convertible_to<Types> ...Convertibles>
1299 /// struct Y { /* ... */ };
1300 /// };
1301 /// \endcode
1302 ///
1303 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1304 /// its type-constraint. When \c Types is supplied with template arguments by
1305 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1306 /// expanded parameter pack. For example, instantiating
1307 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1308 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1309 /// Retrieves the number of parameters in an expanded parameter pack, if any.
1310 UnsignedOrNone getNumExpansionParameters() const { return NumExpanded; }
1311
1312 /// Returns the type constraint associated with this template parameter (if
1313 /// any).
1314 const TypeConstraint *getTypeConstraint() const {
1315 return TypeConstraintInitialized ? getTrailingObjects() : nullptr;
1316 }
1317
1318 void setTypeConstraint(ConceptReference *CR,
1319 Expr *ImmediatelyDeclaredConstraint,
1320 UnsignedOrNone ArgPackSubstIndex);
1321
1322 /// Determine whether this template parameter has a type-constraint.
1323 bool hasTypeConstraint() const {
1324 return HasTypeConstraint;
1325 }
1326
1327 /// \brief Get the associated-constraints of this template parameter.
1328 /// This will either be the immediately-introduced constraint or empty.
1329 ///
1330 /// Use this instead of getTypeConstraint for concepts APIs that
1331 /// accept an ArrayRef of constraint expressions.
1332 void getAssociatedConstraints(
1333 llvm::SmallVectorImpl<AssociatedConstraint> &AC) const {
1334 if (HasTypeConstraint)
1335 AC.emplace_back(Args: getTypeConstraint()->getImmediatelyDeclaredConstraint(),
1336 Args: getTypeConstraint()->getArgPackSubstIndex());
1337 }
1338
1339 SourceRange getSourceRange() const override LLVM_READONLY;
1340
1341 // Implement isa/cast/dyncast/etc.
1342 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
1343 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1344};
1345
1346/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1347/// e.g., "Size" in
1348/// @code
1349/// template<int Size> class array { };
1350/// @endcode
1351class NonTypeTemplateParmDecl final
1352 : public DeclaratorDecl,
1353 protected TemplateParmPosition,
1354 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1355 std::pair<QualType, TypeSourceInfo *>,
1356 Expr *> {
1357 friend class ASTDeclReader;
1358 friend TrailingObjects;
1359
1360 /// The default template argument, if any, and whether or not
1361 /// it was inherited.
1362 using DefArgStorage =
1363 DefaultArgStorage<NonTypeTemplateParmDecl, TemplateArgumentLoc *>;
1364 DefArgStorage DefaultArgument;
1365
1366 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1367 // down here to save memory.
1368
1369 /// Whether this non-type template parameter is a parameter pack.
1370 bool ParameterPack;
1371
1372 /// Whether this non-type template parameter is an "expanded"
1373 /// parameter pack, meaning that its type is a pack expansion and we
1374 /// already know the set of types that expansion expands to.
1375 bool ExpandedParameterPack = false;
1376
1377 /// The number of types in an expanded parameter pack.
1378 unsigned NumExpandedTypes = 0;
1379
1380 size_t numTrailingObjects(
1381 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1382 return NumExpandedTypes;
1383 }
1384
1385 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1386 SourceLocation IdLoc, int D, int P,
1387 const IdentifierInfo *Id, QualType T,
1388 bool ParameterPack, TypeSourceInfo *TInfo)
1389 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1390 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1391
1392 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1393 SourceLocation IdLoc, int D, int P,
1394 const IdentifierInfo *Id, QualType T,
1395 TypeSourceInfo *TInfo,
1396 ArrayRef<QualType> ExpandedTypes,
1397 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1398
1399public:
1400 static NonTypeTemplateParmDecl *
1401 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1402 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1403 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1404
1405 static NonTypeTemplateParmDecl *
1406 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1407 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id,
1408 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1409 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1410
1411 static NonTypeTemplateParmDecl *
1412 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1413 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1414 GlobalDeclID ID,
1415 unsigned NumExpandedTypes,
1416 bool HasTypeConstraint);
1417
1418 using TemplateParmPosition::getDepth;
1419 using TemplateParmPosition::setDepth;
1420 using TemplateParmPosition::getPosition;
1421 using TemplateParmPosition::setPosition;
1422 using TemplateParmPosition::getIndex;
1423
1424 SourceRange getSourceRange() const override LLVM_READONLY;
1425
1426 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1427
1428 /// Determine whether this template parameter has a default
1429 /// argument.
1430 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1431
1432 /// Retrieve the default argument, if any.
1433 const TemplateArgumentLoc &getDefaultArgument() const {
1434 static const TemplateArgumentLoc NoneLoc;
1435 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1436 }
1437
1438 /// Retrieve the location of the default argument, if any.
1439 SourceLocation getDefaultArgumentLoc() const;
1440
1441 /// Determines whether the default argument was inherited
1442 /// from a previous declaration of this template.
1443 bool defaultArgumentWasInherited() const {
1444 return DefaultArgument.isInherited();
1445 }
1446
1447 /// Set the default argument for this template parameter, and
1448 /// whether that default argument was inherited from another
1449 /// declaration.
1450 void setDefaultArgument(const ASTContext &C,
1451 const TemplateArgumentLoc &DefArg);
1452 void setInheritedDefaultArgument(const ASTContext &C,
1453 NonTypeTemplateParmDecl *Parm) {
1454 DefaultArgument.setInherited(C, InheritedFrom: Parm);
1455 }
1456
1457 /// Removes the default argument of this template parameter.
1458 void removeDefaultArgument() { DefaultArgument.clear(); }
1459
1460 /// Whether this parameter is a non-type template parameter pack.
1461 ///
1462 /// If the parameter is a parameter pack, the type may be a
1463 /// \c PackExpansionType. In the following example, the \c Dims parameter
1464 /// is a parameter pack (whose type is 'unsigned').
1465 ///
1466 /// \code
1467 /// template<typename T, unsigned ...Dims> struct multi_array;
1468 /// \endcode
1469 bool isParameterPack() const { return ParameterPack; }
1470
1471 /// Whether this parameter pack is a pack expansion.
1472 ///
1473 /// A non-type template parameter pack is a pack expansion if its type
1474 /// contains an unexpanded parameter pack. In this case, we will have
1475 /// built a PackExpansionType wrapping the type.
1476 bool isPackExpansion() const {
1477 return ParameterPack && getType()->getAs<PackExpansionType>();
1478 }
1479
1480 /// Whether this parameter is a non-type template parameter pack
1481 /// that has a known list of different types at different positions.
1482 ///
1483 /// A parameter pack is an expanded parameter pack when the original
1484 /// parameter pack's type was itself a pack expansion, and that expansion
1485 /// has already been expanded. For example, given:
1486 ///
1487 /// \code
1488 /// template<typename ...Types>
1489 /// struct X {
1490 /// template<Types ...Values>
1491 /// struct Y { /* ... */ };
1492 /// };
1493 /// \endcode
1494 ///
1495 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1496 /// which expands \c Types. When \c Types is supplied with template arguments
1497 /// by instantiating \c X, the instantiation of \c Values becomes an
1498 /// expanded parameter pack. For example, instantiating
1499 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1500 /// pack with expansion types \c int and \c unsigned int.
1501 ///
1502 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1503 /// return the expansion types.
1504 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1505
1506 /// Retrieves the number of expansion types in an expanded parameter
1507 /// pack.
1508 unsigned getNumExpansionTypes() const {
1509 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1510 return NumExpandedTypes;
1511 }
1512
1513 /// Retrieve a particular expansion type within an expanded parameter
1514 /// pack.
1515 QualType getExpansionType(unsigned I) const {
1516 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1517 auto TypesAndInfos =
1518 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1519 return TypesAndInfos[I].first;
1520 }
1521
1522 /// Retrieve a particular expansion type source info within an
1523 /// expanded parameter pack.
1524 TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
1525 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1526 auto TypesAndInfos =
1527 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1528 return TypesAndInfos[I].second;
1529 }
1530
1531 /// Return the constraint introduced by the placeholder type of this non-type
1532 /// template parameter (if any).
1533 Expr *getPlaceholderTypeConstraint() const {
1534 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1535 nullptr;
1536 }
1537
1538 void setPlaceholderTypeConstraint(Expr *E) {
1539 *getTrailingObjects<Expr *>() = E;
1540 }
1541
1542 /// Determine whether this non-type template parameter's type has a
1543 /// placeholder with a type-constraint.
1544 bool hasPlaceholderTypeConstraint() const {
1545 auto *AT = getType()->getContainedAutoType();
1546 return AT && AT->isConstrained();
1547 }
1548
1549 /// \brief Get the associated-constraints of this template parameter.
1550 /// This will either be a vector of size 1 containing the immediately-declared
1551 /// constraint introduced by the placeholder type, or an empty vector.
1552 ///
1553 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1554 /// concepts APIs that accept an ArrayRef of constraint expressions.
1555 void getAssociatedConstraints(
1556 llvm::SmallVectorImpl<AssociatedConstraint> &AC) const {
1557 if (Expr *E = getPlaceholderTypeConstraint())
1558 AC.emplace_back(Args&: E);
1559 }
1560
1561 // Implement isa/cast/dyncast/etc.
1562 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
1563 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1564};
1565
1566/// TemplateTemplateParmDecl - Declares a template template parameter,
1567/// e.g., "T" in
1568/// @code
1569/// template <template <typename> class T> class container { };
1570/// @endcode
1571/// A template template parameter is a TemplateDecl because it defines the
1572/// name of a template and the template parameters allowable for substitution.
1573class TemplateTemplateParmDecl final
1574 : public TemplateDecl,
1575 protected TemplateParmPosition,
1576 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1577 TemplateParameterList *> {
1578 /// The default template argument, if any.
1579 using DefArgStorage =
1580 DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>;
1581 DefArgStorage DefaultArgument;
1582
1583 LLVM_PREFERRED_TYPE(TemplateNameKind)
1584 unsigned ParameterKind : 3;
1585
1586 /// Whether this template template parameter was declaration with
1587 /// the 'typename' keyword.
1588 ///
1589 /// If false, it was declared with the 'class' keyword.
1590 LLVM_PREFERRED_TYPE(bool)
1591 unsigned Typename : 1;
1592
1593 /// Whether this parameter is a parameter pack.
1594 LLVM_PREFERRED_TYPE(bool)
1595 unsigned ParameterPack : 1;
1596
1597 /// Whether this template template parameter is an "expanded"
1598 /// parameter pack, meaning that it is a pack expansion and we
1599 /// already know the set of template parameters that expansion expands to.
1600 LLVM_PREFERRED_TYPE(bool)
1601 unsigned ExpandedParameterPack : 1;
1602
1603 /// The number of parameters in an expanded parameter pack.
1604 unsigned NumExpandedParams = 0;
1605
1606 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1607 bool ParameterPack, IdentifierInfo *Id,
1608 TemplateNameKind ParameterKind, bool Typename,
1609 TemplateParameterList *Params)
1610 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1611 TemplateParmPosition(D, P), ParameterKind(ParameterKind),
1612 Typename(Typename), ParameterPack(ParameterPack),
1613 ExpandedParameterPack(false) {}
1614
1615 TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, int D, int P,
1616 IdentifierInfo *Id, TemplateNameKind ParameterKind,
1617 bool Typename, TemplateParameterList *Params,
1618 ArrayRef<TemplateParameterList *> Expansions);
1619
1620 void anchor() override;
1621
1622public:
1623 friend class ASTDeclReader;
1624 friend class ASTDeclWriter;
1625 friend TrailingObjects;
1626
1627 static TemplateTemplateParmDecl *
1628 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1629 bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind,
1630 bool Typename, TemplateParameterList *Params);
1631
1632 static TemplateTemplateParmDecl *
1633 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
1634 IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename,
1635 TemplateParameterList *Params,
1636 ArrayRef<TemplateParameterList *> Expansions);
1637
1638 static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
1639 GlobalDeclID ID);
1640 static TemplateTemplateParmDecl *
1641 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1642
1643 using TemplateParmPosition::getDepth;
1644 using TemplateParmPosition::setDepth;
1645 using TemplateParmPosition::getPosition;
1646 using TemplateParmPosition::setPosition;
1647 using TemplateParmPosition::getIndex;
1648
1649 /// Whether this template template parameter was declared with
1650 /// the 'typename' keyword.
1651 bool wasDeclaredWithTypename() const { return Typename; }
1652
1653 /// Set whether this template template parameter was declared with
1654 /// the 'typename' or 'class' keyword.
1655 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1656
1657 /// Whether this template template parameter is a template
1658 /// parameter pack.
1659 ///
1660 /// \code
1661 /// template<template <class T> ...MetaFunctions> struct Apply;
1662 /// \endcode
1663 bool isParameterPack() const { return ParameterPack; }
1664
1665 /// Whether this parameter pack is a pack expansion.
1666 ///
1667 /// A template template parameter pack is a pack expansion if its template
1668 /// parameter list contains an unexpanded parameter pack.
1669 bool isPackExpansion() const {
1670 return ParameterPack &&
1671 getTemplateParameters()->containsUnexpandedParameterPack();
1672 }
1673
1674 /// Whether this parameter is a template template parameter pack that
1675 /// has a known list of different template parameter lists at different
1676 /// positions.
1677 ///
1678 /// A parameter pack is an expanded parameter pack when the original parameter
1679 /// pack's template parameter list was itself a pack expansion, and that
1680 /// expansion has already been expanded. For exampe, given:
1681 ///
1682 /// \code
1683 /// template<typename...Types> struct Outer {
1684 /// template<template<Types> class...Templates> struct Inner;
1685 /// };
1686 /// \endcode
1687 ///
1688 /// The parameter pack \c Templates is a pack expansion, which expands the
1689 /// pack \c Types. When \c Types is supplied with template arguments by
1690 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1691 /// parameter pack.
1692 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1693
1694 /// Retrieves the number of expansion template parameters in
1695 /// an expanded parameter pack.
1696 unsigned getNumExpansionTemplateParameters() const {
1697 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1698 return NumExpandedParams;
1699 }
1700
1701 /// Retrieve a particular expansion type within an expanded parameter
1702 /// pack.
1703 TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
1704 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1705 return getTrailingObjects()[I];
1706 }
1707
1708 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1709
1710 /// Determine whether this template parameter has a default
1711 /// argument.
1712 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1713
1714 /// Retrieve the default argument, if any.
1715 const TemplateArgumentLoc &getDefaultArgument() const {
1716 static const TemplateArgumentLoc NoneLoc;
1717 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1718 }
1719
1720 /// Retrieve the location of the default argument, if any.
1721 SourceLocation getDefaultArgumentLoc() const;
1722
1723 /// Determines whether the default argument was inherited
1724 /// from a previous declaration of this template.
1725 bool defaultArgumentWasInherited() const {
1726 return DefaultArgument.isInherited();
1727 }
1728
1729 /// Set the default argument for this template parameter, and
1730 /// whether that default argument was inherited from another
1731 /// declaration.
1732 void setDefaultArgument(const ASTContext &C,
1733 const TemplateArgumentLoc &DefArg);
1734 void setInheritedDefaultArgument(const ASTContext &C,
1735 TemplateTemplateParmDecl *Prev) {
1736 DefaultArgument.setInherited(C, InheritedFrom: Prev);
1737 }
1738
1739 /// Removes the default argument of this template parameter.
1740 void removeDefaultArgument() { DefaultArgument.clear(); }
1741
1742 SourceRange getSourceRange() const override LLVM_READONLY {
1743 SourceLocation End = getLocation();
1744 if (hasDefaultArgument() && !defaultArgumentWasInherited())
1745 End = getDefaultArgument().getSourceRange().getEnd();
1746 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1747 }
1748
1749 TemplateNameKind templateParameterKind() const {
1750 return static_cast<TemplateNameKind>(ParameterKind);
1751 }
1752
1753 bool isTypeConceptTemplateParam() const {
1754 return templateParameterKind() == TemplateNameKind::TNK_Concept_template &&
1755 getTemplateParameters()->size() > 0 &&
1756 isa<TemplateTypeParmDecl>(Val: getTemplateParameters()->getParam(Idx: 0));
1757 }
1758
1759 // Implement isa/cast/dyncast/etc.
1760 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
1761 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1762};
1763
1764/// Represents the builtin template declaration which is used to
1765/// implement __make_integer_seq and other builtin templates. It serves
1766/// no real purpose beyond existing as a place to hold template parameters.
1767class BuiltinTemplateDecl : public TemplateDecl {
1768 BuiltinTemplateKind BTK;
1769
1770 BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1771 DeclarationName Name, BuiltinTemplateKind BTK);
1772
1773 void anchor() override;
1774
1775public:
1776 // Implement isa/cast/dyncast support
1777 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
1778 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1779
1780 static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
1781 DeclarationName Name,
1782 BuiltinTemplateKind BTK) {
1783 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1784 }
1785
1786 SourceRange getSourceRange() const override LLVM_READONLY {
1787 return {};
1788 }
1789
1790 BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
1791
1792 bool isPackProducingBuiltinTemplate() const;
1793};
1794bool isPackProducingBuiltinTemplateName(TemplateName N);
1795
1796/// Provides information about an explicit instantiation of a variable or class
1797/// template.
1798struct ExplicitInstantiationInfo {
1799 /// The template arguments as written..
1800 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten = nullptr;
1801
1802 /// The location of the extern keyword.
1803 SourceLocation ExternKeywordLoc;
1804
1805 /// The location of the template keyword.
1806 SourceLocation TemplateKeywordLoc;
1807
1808 ExplicitInstantiationInfo() = default;
1809};
1810
1811using SpecializationOrInstantiationInfo =
1812 llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
1813 ExplicitInstantiationInfo *>;
1814
1815/// Represents a class template specialization, which refers to
1816/// a class template with a given set of template arguments.
1817///
1818/// Class template specializations represent both explicit
1819/// specialization of class templates, as in the example below, and
1820/// implicit instantiations of class templates.
1821///
1822/// \code
1823/// template<typename T> class array;
1824///
1825/// template<>
1826/// class array<bool> { }; // class template specialization array<bool>
1827/// \endcode
1828class ClassTemplateSpecializationDecl : public CXXRecordDecl,
1829 public llvm::FoldingSetNode {
1830 /// Structure that stores information about a class template
1831 /// specialization that was instantiated from a class template partial
1832 /// specialization.
1833 struct SpecializedPartialSpecialization {
1834 /// The class template partial specialization from which this
1835 /// class template specialization was instantiated.
1836 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1837
1838 /// The template argument list deduced for the class template
1839 /// partial specialization itself.
1840 const TemplateArgumentList *TemplateArgs;
1841 };
1842
1843 /// The template that this specialization specializes
1844 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1845 SpecializedTemplate;
1846
1847 /// Further info for explicit template specialization/instantiation.
1848 /// Does not apply to implicit specializations.
1849 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
1850
1851 /// The template arguments used to describe this specialization.
1852 const TemplateArgumentList *TemplateArgs;
1853
1854 /// The point where this template was instantiated (if any)
1855 SourceLocation PointOfInstantiation;
1856
1857 /// The kind of specialization this declaration refers to.
1858 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1859 unsigned SpecializationKind : 3;
1860
1861 /// Indicate that we have matched a parameter pack with a non pack
1862 /// argument, when the opposite match is also allowed.
1863 /// This needs to be cached as deduction is performed during declaration,
1864 /// and we need the information to be preserved so that it is consistent
1865 /// during instantiation.
1866 LLVM_PREFERRED_TYPE(bool)
1867 unsigned StrictPackMatch : 1;
1868
1869protected:
1870 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
1871 DeclContext *DC, SourceLocation StartLoc,
1872 SourceLocation IdLoc,
1873 ClassTemplateDecl *SpecializedTemplate,
1874 ArrayRef<TemplateArgument> Args,
1875 bool StrictPackMatch,
1876 ClassTemplateSpecializationDecl *PrevDecl);
1877
1878 ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
1879
1880public:
1881 friend class ASTDeclReader;
1882 friend class ASTDeclWriter;
1883
1884 static ClassTemplateSpecializationDecl *
1885 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1886 SourceLocation StartLoc, SourceLocation IdLoc,
1887 ClassTemplateDecl *SpecializedTemplate,
1888 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
1889 ClassTemplateSpecializationDecl *PrevDecl);
1890 static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
1891 GlobalDeclID ID);
1892
1893 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1894 bool Qualified) const override;
1895
1896 ClassTemplateSpecializationDecl *getMostRecentDecl() {
1897 return cast<ClassTemplateSpecializationDecl>(
1898 Val: CXXRecordDecl::getMostRecentDecl());
1899 }
1900
1901 ClassTemplateSpecializationDecl *getDefinitionOrSelf() const {
1902 return cast<ClassTemplateSpecializationDecl>(
1903 Val: CXXRecordDecl::getDefinitionOrSelf());
1904 }
1905
1906 /// Retrieve the template that this specialization specializes.
1907 ClassTemplateDecl *getSpecializedTemplate() const;
1908
1909 /// Retrieve the template arguments of the class template
1910 /// specialization.
1911 const TemplateArgumentList &getTemplateArgs() const {
1912 return *TemplateArgs;
1913 }
1914
1915 void setTemplateArgs(TemplateArgumentList *Args) {
1916 TemplateArgs = Args;
1917 }
1918
1919 /// Determine the kind of specialization that this
1920 /// declaration represents.
1921 TemplateSpecializationKind getSpecializationKind() const {
1922 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1923 }
1924
1925 bool isExplicitSpecialization() const {
1926 return getSpecializationKind() == TSK_ExplicitSpecialization;
1927 }
1928
1929 /// Is this an explicit specialization at class scope (within the class that
1930 /// owns the primary template)? For example:
1931 ///
1932 /// \code
1933 /// template<typename T> struct Outer {
1934 /// template<typename U> struct Inner;
1935 /// template<> struct Inner; // class-scope explicit specialization
1936 /// };
1937 /// \endcode
1938 bool isClassScopeExplicitSpecialization() const {
1939 return isExplicitSpecialization() &&
1940 isa<CXXRecordDecl>(Val: getLexicalDeclContext());
1941 }
1942
1943 /// True if this declaration is an explicit specialization,
1944 /// explicit instantiation declaration, or explicit instantiation
1945 /// definition.
1946 bool isExplicitInstantiationOrSpecialization() const {
1947 return isTemplateExplicitInstantiationOrSpecialization(
1948 Kind: getTemplateSpecializationKind());
1949 }
1950
1951 void setSpecializedTemplate(ClassTemplateDecl *Specialized) {
1952 SpecializedTemplate = Specialized;
1953 }
1954
1955 void setSpecializationKind(TemplateSpecializationKind TSK) {
1956 SpecializationKind = TSK;
1957 }
1958
1959 bool hasStrictPackMatch() const { return StrictPackMatch; }
1960
1961 void setStrictPackMatch(bool Val) { StrictPackMatch = Val; }
1962
1963 /// Get the point of instantiation (if any), or null if none.
1964 SourceLocation getPointOfInstantiation() const {
1965 return PointOfInstantiation;
1966 }
1967
1968 void setPointOfInstantiation(SourceLocation Loc) {
1969 assert(Loc.isValid() && "point of instantiation must be valid!");
1970 PointOfInstantiation = Loc;
1971 }
1972
1973 /// If this class template specialization is an instantiation of
1974 /// a template (rather than an explicit specialization), return the
1975 /// class template or class template partial specialization from which it
1976 /// was instantiated.
1977 llvm::PointerUnion<ClassTemplateDecl *,
1978 ClassTemplatePartialSpecializationDecl *>
1979 getInstantiatedFrom() const {
1980 if (!isTemplateInstantiation(Kind: getSpecializationKind()))
1981 return llvm::PointerUnion<ClassTemplateDecl *,
1982 ClassTemplatePartialSpecializationDecl *>();
1983
1984 return getSpecializedTemplateOrPartial();
1985 }
1986
1987 /// Retrieve the class template or class template partial
1988 /// specialization which was specialized by this.
1989 llvm::PointerUnion<ClassTemplateDecl *,
1990 ClassTemplatePartialSpecializationDecl *>
1991 getSpecializedTemplateOrPartial() const {
1992 if (const auto *PartialSpec =
1993 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1994 return PartialSpec->PartialSpecialization;
1995
1996 return cast<ClassTemplateDecl *>(Val: SpecializedTemplate);
1997 }
1998
1999 /// Retrieve the set of template arguments that should be used
2000 /// to instantiate members of the class template or class template partial
2001 /// specialization from which this class template specialization was
2002 /// instantiated.
2003 ///
2004 /// \returns For a class template specialization instantiated from the primary
2005 /// template, this function will return the same template arguments as
2006 /// getTemplateArgs(). For a class template specialization instantiated from
2007 /// a class template partial specialization, this function will return the
2008 /// deduced template arguments for the class template partial specialization
2009 /// itself.
2010 const TemplateArgumentList &getTemplateInstantiationArgs() const {
2011 if (const auto *PartialSpec =
2012 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2013 return *PartialSpec->TemplateArgs;
2014
2015 return getTemplateArgs();
2016 }
2017
2018 /// Note that this class template specialization is actually an
2019 /// instantiation of the given class template partial specialization whose
2020 /// template arguments have been deduced.
2021 void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
2022 const TemplateArgumentList *TemplateArgs) {
2023 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2024 "Already set to a class template partial specialization!");
2025 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2026 PS->PartialSpecialization = PartialSpec;
2027 PS->TemplateArgs = TemplateArgs;
2028 SpecializedTemplate = PS;
2029 }
2030
2031 /// Note that this class template specialization is an instantiation
2032 /// of the given class template.
2033 void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
2034 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2035 "Previously set to a class template partial specialization!");
2036 SpecializedTemplate = TemplDecl;
2037 }
2038
2039 /// Retrieve the template argument list as written in the sources,
2040 /// if any.
2041 const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2042 if (auto *Info =
2043 dyn_cast_if_present<ExplicitInstantiationInfo *>(Val: ExplicitInfo))
2044 return Info->TemplateArgsAsWritten;
2045 return cast<const ASTTemplateArgumentListInfo *>(Val: ExplicitInfo);
2046 }
2047
2048 /// Set the template argument list as written in the sources.
2049 void
2050 setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) {
2051 if (auto *Info =
2052 dyn_cast_if_present<ExplicitInstantiationInfo *>(Val&: ExplicitInfo))
2053 Info->TemplateArgsAsWritten = ArgsWritten;
2054 else
2055 ExplicitInfo = ArgsWritten;
2056 }
2057
2058 /// Set the template argument list as written in the sources.
2059 void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) {
2060 setTemplateArgsAsWritten(
2061 ASTTemplateArgumentListInfo::Create(C: getASTContext(), List: ArgsInfo));
2062 }
2063
2064 /// Gets the location of the extern keyword, if present.
2065 SourceLocation getExternKeywordLoc() const {
2066 if (auto *Info =
2067 dyn_cast_if_present<ExplicitInstantiationInfo *>(Val: ExplicitInfo))
2068 return Info->ExternKeywordLoc;
2069 return SourceLocation();
2070 }
2071
2072 /// Sets the location of the extern keyword.
2073 void setExternKeywordLoc(SourceLocation Loc);
2074
2075 /// Gets the location of the template keyword, if present.
2076 SourceLocation getTemplateKeywordLoc() const {
2077 if (auto *Info =
2078 dyn_cast_if_present<ExplicitInstantiationInfo *>(Val: ExplicitInfo))
2079 return Info->TemplateKeywordLoc;
2080 return SourceLocation();
2081 }
2082
2083 /// Sets the location of the template keyword.
2084 void setTemplateKeywordLoc(SourceLocation Loc);
2085
2086 SourceRange getSourceRange() const override LLVM_READONLY;
2087
2088 void Profile(llvm::FoldingSetNodeID &ID) const {
2089 Profile(ID, TemplateArgs: TemplateArgs->asArray(), Context: getASTContext());
2090 }
2091
2092 static void
2093 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2094 const ASTContext &Context) {
2095 ID.AddInteger(I: TemplateArgs.size());
2096 for (const TemplateArgument &TemplateArg : TemplateArgs)
2097 TemplateArg.Profile(ID, Context);
2098 }
2099
2100 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
2101
2102 static bool classofKind(Kind K) {
2103 return K >= firstClassTemplateSpecialization &&
2104 K <= lastClassTemplateSpecialization;
2105 }
2106};
2107
2108class ClassTemplatePartialSpecializationDecl
2109 : public ClassTemplateSpecializationDecl {
2110 /// The list of template parameters
2111 TemplateParameterList *TemplateParams = nullptr;
2112
2113 /// The class template partial specialization from which this
2114 /// class template partial specialization was instantiated.
2115 ///
2116 /// The boolean value will be true to indicate that this class template
2117 /// partial specialization was specialized at this level.
2118 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2119 InstantiatedFromMember;
2120
2121 mutable CanQualType CanonInjectedTST;
2122
2123 ClassTemplatePartialSpecializationDecl(
2124 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
2125 SourceLocation IdLoc, TemplateParameterList *Params,
2126 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
2127 CanQualType CanonInjectedTST,
2128 ClassTemplatePartialSpecializationDecl *PrevDecl);
2129
2130 ClassTemplatePartialSpecializationDecl(ASTContext &C)
2131 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2132 InstantiatedFromMember(nullptr, false) {}
2133
2134 void anchor() override;
2135
2136public:
2137 friend class ASTDeclReader;
2138 friend class ASTDeclWriter;
2139
2140 static ClassTemplatePartialSpecializationDecl *
2141 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2142 SourceLocation StartLoc, SourceLocation IdLoc,
2143 TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
2144 ArrayRef<TemplateArgument> Args, CanQualType CanonInjectedTST,
2145 ClassTemplatePartialSpecializationDecl *PrevDecl);
2146
2147 static ClassTemplatePartialSpecializationDecl *
2148 CreateDeserialized(ASTContext &C, GlobalDeclID ID);
2149
2150 ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
2151 return cast<ClassTemplatePartialSpecializationDecl>(
2152 Val: static_cast<ClassTemplateSpecializationDecl *>(
2153 this)->getMostRecentDecl());
2154 }
2155
2156 /// Get the list of template parameters
2157 TemplateParameterList *getTemplateParameters() const {
2158 return TemplateParams;
2159 }
2160
2161 /// \brief All associated constraints of this partial specialization,
2162 /// including the requires clause and any constraints derived from
2163 /// constrained-parameters.
2164 ///
2165 /// The constraints in the resulting list are to be treated as if in a
2166 /// conjunction ("and").
2167 void getAssociatedConstraints(
2168 llvm::SmallVectorImpl<AssociatedConstraint> &AC) const {
2169 TemplateParams->getAssociatedConstraints(AC);
2170 }
2171
2172 bool hasAssociatedConstraints() const {
2173 return TemplateParams->hasAssociatedConstraints();
2174 }
2175
2176 /// Retrieve the member class template partial specialization from
2177 /// which this particular class template partial specialization was
2178 /// instantiated.
2179 ///
2180 /// \code
2181 /// template<typename T>
2182 /// struct Outer {
2183 /// template<typename U> struct Inner;
2184 /// template<typename U> struct Inner<U*> { }; // #1
2185 /// };
2186 ///
2187 /// Outer<float>::Inner<int*> ii;
2188 /// \endcode
2189 ///
2190 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2191 /// end up instantiating the partial specialization
2192 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2193 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2194 /// \c Outer<float>::Inner<U*>, this function would return
2195 /// \c Outer<T>::Inner<U*>.
2196 ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2197 const auto *First =
2198 cast<ClassTemplatePartialSpecializationDecl>(Val: getFirstDecl());
2199 return First->InstantiatedFromMember.getPointer();
2200 }
2201 ClassTemplatePartialSpecializationDecl *
2202 getInstantiatedFromMemberTemplate() const {
2203 return getInstantiatedFromMember();
2204 }
2205
2206 void setInstantiatedFromMember(
2207 ClassTemplatePartialSpecializationDecl *PartialSpec) {
2208 auto *First = cast<ClassTemplatePartialSpecializationDecl>(Val: getFirstDecl());
2209 First->InstantiatedFromMember.setPointer(PartialSpec);
2210 }
2211
2212 /// Determines whether this class template partial specialization
2213 /// template was a specialization of a member partial specialization.
2214 ///
2215 /// In the following example, the member template partial specialization
2216 /// \c X<int>::Inner<T*> is a member specialization.
2217 ///
2218 /// \code
2219 /// template<typename T>
2220 /// struct X {
2221 /// template<typename U> struct Inner;
2222 /// template<typename U> struct Inner<U*>;
2223 /// };
2224 ///
2225 /// template<> template<typename T>
2226 /// struct X<int>::Inner<T*> { /* ... */ };
2227 /// \endcode
2228 bool isMemberSpecialization() const {
2229 const auto *First =
2230 cast<ClassTemplatePartialSpecializationDecl>(Val: getFirstDecl());
2231 return First->InstantiatedFromMember.getInt();
2232 }
2233
2234 /// Note that this member template is a specialization.
2235 /// A partial specialization may be a member specialization even if it is not
2236 /// an instantiation of a member partial specialization.
2237 void setMemberSpecialization() {
2238 auto *First = cast<ClassTemplatePartialSpecializationDecl>(Val: getFirstDecl());
2239 return First->InstantiatedFromMember.setInt(true);
2240 }
2241
2242 /// Retrieves the canonical injected specialization type for this partial
2243 /// specialization.
2244 CanQualType
2245 getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const;
2246
2247 SourceRange getSourceRange() const override LLVM_READONLY;
2248
2249 void Profile(llvm::FoldingSetNodeID &ID) const {
2250 Profile(ID, TemplateArgs: getTemplateArgs().asArray(), TPL: getTemplateParameters(),
2251 Context: getASTContext());
2252 }
2253
2254 static void
2255 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2256 TemplateParameterList *TPL, const ASTContext &Context);
2257
2258 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
2259
2260 static bool classofKind(Kind K) {
2261 return K == ClassTemplatePartialSpecialization;
2262 }
2263};
2264
2265/// Declaration of a class template.
2266class ClassTemplateDecl : public RedeclarableTemplateDecl {
2267protected:
2268 /// Data that is common to all of the declarations of a given
2269 /// class template.
2270 struct Common : CommonBase {
2271 /// The class template specializations for this class
2272 /// template, including explicit specializations and instantiations.
2273 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2274
2275 /// The class template partial specializations for this class
2276 /// template.
2277 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2278 PartialSpecializations;
2279
2280 /// The Injected Template Specialization Type for this declaration.
2281 CanQualType CanonInjectedTST;
2282
2283 Common() = default;
2284 };
2285
2286 /// Retrieve the set of specializations of this class template.
2287 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2288 getSpecializations() const;
2289
2290 /// Retrieve the set of partial specializations of this class
2291 /// template.
2292 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2293 getPartialSpecializations() const;
2294
2295 ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
2296 DeclarationName Name, TemplateParameterList *Params,
2297 NamedDecl *Decl)
2298 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2299
2300 CommonBase *newCommon(ASTContext &C) const override;
2301
2302 Common *getCommonPtr() const {
2303 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2304 }
2305
2306 void setCommonPtr(Common *C) { RedeclarableTemplateDecl::Common = C; }
2307
2308public:
2309
2310 friend class ASTDeclReader;
2311 friend class ASTDeclWriter;
2312 friend class TemplateDeclInstantiator;
2313
2314 /// Load any lazily-loaded specializations from the external source.
2315 void LoadLazySpecializations(bool OnlyPartial = false) const;
2316
2317 /// Get the underlying class declarations of the template.
2318 CXXRecordDecl *getTemplatedDecl() const {
2319 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2320 }
2321
2322 /// Returns whether this template declaration defines the primary
2323 /// class pattern.
2324 bool isThisDeclarationADefinition() const {
2325 return getTemplatedDecl()->isThisDeclarationADefinition();
2326 }
2327
2328 /// \brief Create a class template node.
2329 static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
2330 SourceLocation L,
2331 DeclarationName Name,
2332 TemplateParameterList *Params,
2333 NamedDecl *Decl);
2334
2335 /// Create an empty class template node.
2336 static ClassTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
2337
2338 /// Return the specialization with the provided arguments if it exists,
2339 /// otherwise return the insertion point.
2340 ClassTemplateSpecializationDecl *
2341 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2342
2343 /// Insert the specified specialization knowing that it is not already
2344 /// in. InsertPos must be obtained from findSpecialization.
2345 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2346
2347 ClassTemplateDecl *getCanonicalDecl() override {
2348 return cast<ClassTemplateDecl>(
2349 Val: RedeclarableTemplateDecl::getCanonicalDecl());
2350 }
2351 const ClassTemplateDecl *getCanonicalDecl() const {
2352 return cast<ClassTemplateDecl>(
2353 Val: RedeclarableTemplateDecl::getCanonicalDecl());
2354 }
2355
2356 /// Retrieve the previous declaration of this class template, or
2357 /// nullptr if no such declaration exists.
2358 ClassTemplateDecl *getPreviousDecl() {
2359 return cast_or_null<ClassTemplateDecl>(
2360 Val: static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2361 }
2362 const ClassTemplateDecl *getPreviousDecl() const {
2363 return cast_or_null<ClassTemplateDecl>(
2364 Val: static_cast<const RedeclarableTemplateDecl *>(
2365 this)->getPreviousDecl());
2366 }
2367
2368 ClassTemplateDecl *getMostRecentDecl() {
2369 return cast<ClassTemplateDecl>(
2370 Val: static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
2371 }
2372 const ClassTemplateDecl *getMostRecentDecl() const {
2373 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2374 }
2375
2376 ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
2377 return cast_or_null<ClassTemplateDecl>(
2378 Val: RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
2379 }
2380
2381 /// Return the partial specialization with the provided arguments if it
2382 /// exists, otherwise return the insertion point.
2383 ClassTemplatePartialSpecializationDecl *
2384 findPartialSpecialization(ArrayRef<TemplateArgument> Args,
2385 TemplateParameterList *TPL, void *&InsertPos);
2386
2387 /// Insert the specified partial specialization knowing that it is not
2388 /// already in. InsertPos must be obtained from findPartialSpecialization.
2389 void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
2390 void *InsertPos);
2391
2392 /// Retrieve the partial specializations as an ordered list.
2393 void getPartialSpecializations(
2394 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const;
2395
2396 /// Find a class template partial specialization with the given
2397 /// type T.
2398 ///
2399 /// \param T a dependent type that names a specialization of this class
2400 /// template.
2401 ///
2402 /// \returns the class template partial specialization that exactly matches
2403 /// the type \p T, or nullptr if no such partial specialization exists.
2404 ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
2405
2406 /// Find a class template partial specialization which was instantiated
2407 /// from the given member partial specialization.
2408 ///
2409 /// \param D a member class template partial specialization.
2410 ///
2411 /// \returns the class template partial specialization which was instantiated
2412 /// from the given member partial specialization, or nullptr if no such
2413 /// partial specialization exists.
2414 ClassTemplatePartialSpecializationDecl *
2415 findPartialSpecInstantiatedFromMember(
2416 ClassTemplatePartialSpecializationDecl *D);
2417
2418 /// Retrieve the canonical template specialization type of the
2419 /// injected-class-name for this class template.
2420 ///
2421 /// The injected-class-name for a class template \c X is \c
2422 /// X<template-args>, where \c template-args is formed from the
2423 /// template arguments that correspond to the template parameters of
2424 /// \c X. For example:
2425 ///
2426 /// \code
2427 /// template<typename T, int N>
2428 /// struct array {
2429 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2430 /// };
2431 /// \endcode
2432 CanQualType
2433 getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const;
2434
2435 using spec_iterator = SpecIterator<ClassTemplateSpecializationDecl>;
2436 using spec_range = llvm::iterator_range<spec_iterator>;
2437
2438 spec_range specializations() const {
2439 return spec_range(spec_begin(), spec_end());
2440 }
2441
2442 spec_iterator spec_begin() const {
2443 return makeSpecIterator(Specs&: getSpecializations(), isEnd: false);
2444 }
2445
2446 spec_iterator spec_end() const {
2447 return makeSpecIterator(Specs&: getSpecializations(), isEnd: true);
2448 }
2449
2450 // Implement isa/cast/dyncast support
2451 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
2452 static bool classofKind(Kind K) { return K == ClassTemplate; }
2453};
2454
2455/// Declaration of a friend template.
2456///
2457/// For example:
2458/// \code
2459/// template \<typename T> class A {
2460/// friend class MyVector<T>; // not a friend template
2461/// template \<typename U> friend class B; // friend class template
2462/// template \<typename U> friend class Foo<T>::Nested; // friend template
2463/// };
2464/// \endcode
2465class FriendTemplateDecl final
2466 : public FriendDecl,
2467 private llvm::TrailingObjects<FriendTemplateDecl,
2468 TemplateParameterList *> {
2469 void anchor() override;
2470
2471private:
2472 unsigned NumTPLists = 0;
2473 TemplateName Template;
2474
2475 FriendTemplateDecl(DeclContext *DC, SourceLocation Loc, FriendUnion Friend,
2476 SourceLocation FriendLoc, SourceLocation EllipsisLoc,
2477 ArrayRef<TemplateParameterList *> FriendTPLists,
2478 TemplateName Template = {})
2479 : FriendDecl(Decl::FriendTemplate, DC, Loc, Friend, FriendLoc,
2480 EllipsisLoc),
2481 NumTPLists(FriendTPLists.size()), Template(Template) {
2482 assert(!FriendTPLists.empty());
2483 llvm::copy(Range&: FriendTPLists, Out: getTrailingObjects());
2484 }
2485
2486 FriendTemplateDecl(EmptyShell Empty, unsigned NumFriendTPLists)
2487 : FriendDecl(Decl::FriendTemplate, Empty), NumTPLists(NumFriendTPLists) {
2488 assert(NumFriendTPLists != 0);
2489 }
2490
2491public:
2492 friend class ASTDeclReader;
2493 friend class ASTDeclWriter;
2494 friend TrailingObjects;
2495
2496 enum class FriendTemplateEntityKind { Type, Template, Decl };
2497
2498 static FriendTemplateDecl *
2499 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2500 FriendUnion Friend, SourceLocation FriendLoc,
2501 ArrayRef<TemplateParameterList *> FriendTPLists,
2502 SourceLocation EllipsisLoc = {}, TemplateName Template = {});
2503
2504 static FriendTemplateDecl *
2505 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2506 TemplateName Template, SourceLocation FriendLoc,
2507 ArrayRef<TemplateParameterList *> FriendTPLists,
2508 SourceLocation EllipsisLoc = {});
2509
2510 static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
2511 unsigned NumFriendTPLists);
2512
2513 SourceRange getSourceRange() const override LLVM_READONLY;
2514
2515 TemplateName getFriendTemplateName() const { return Template; }
2516
2517 FriendTemplateEntityKind getFriendKind() const {
2518 if (getFriendType())
2519 return FriendTemplateEntityKind::Type;
2520 if (Template.isNull())
2521 return FriendTemplateEntityKind::Decl;
2522 return FriendTemplateEntityKind::Template;
2523 }
2524
2525 NamedDecl *getFriendDecl() const override {
2526 if (NamedDecl *ND = Friend.dyn_cast<NamedDecl *>())
2527 return ND;
2528 return Template.getAsTemplateDecl();
2529 }
2530
2531 ArrayRef<TemplateParameterList *> getTemplateParameterLists() const {
2532 return ArrayRef(getTrailingObjects(), NumTPLists);
2533 }
2534
2535 // Implement isa/cast/dyncast/etc.
2536 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
2537 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2538};
2539
2540/// Declaration of an alias template.
2541///
2542/// For example:
2543/// \code
2544/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
2545/// \endcode
2546class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
2547protected:
2548 using Common = CommonBase;
2549
2550 TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
2551 DeclarationName Name, TemplateParameterList *Params,
2552 NamedDecl *Decl)
2553 : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
2554 Decl) {}
2555
2556 CommonBase *newCommon(ASTContext &C) const override;
2557
2558 Common *getCommonPtr() {
2559 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2560 }
2561
2562public:
2563 friend class ASTDeclReader;
2564 friend class ASTDeclWriter;
2565
2566 /// Get the underlying function declaration of the template.
2567 TypeAliasDecl *getTemplatedDecl() const {
2568 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2569 }
2570
2571
2572 TypeAliasTemplateDecl *getCanonicalDecl() override {
2573 return cast<TypeAliasTemplateDecl>(
2574 Val: RedeclarableTemplateDecl::getCanonicalDecl());
2575 }
2576 const TypeAliasTemplateDecl *getCanonicalDecl() const {
2577 return cast<TypeAliasTemplateDecl>(
2578 Val: RedeclarableTemplateDecl::getCanonicalDecl());
2579 }
2580
2581 /// Retrieve the previous declaration of this function template, or
2582 /// nullptr if no such declaration exists.
2583 TypeAliasTemplateDecl *getPreviousDecl() {
2584 return cast_or_null<TypeAliasTemplateDecl>(
2585 Val: static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2586 }
2587 const TypeAliasTemplateDecl *getPreviousDecl() const {
2588 return cast_or_null<TypeAliasTemplateDecl>(
2589 Val: static_cast<const RedeclarableTemplateDecl *>(
2590 this)->getPreviousDecl());
2591 }
2592
2593 TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() const {
2594 return cast_or_null<TypeAliasTemplateDecl>(
2595 Val: RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
2596 }
2597
2598 /// Create a function template node.
2599 static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
2600 SourceLocation L,
2601 DeclarationName Name,
2602 TemplateParameterList *Params,
2603 NamedDecl *Decl);
2604
2605 /// Create an empty alias template node.
2606 static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C,
2607 GlobalDeclID ID);
2608
2609 // Implement isa/cast/dyncast support
2610 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
2611 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2612};
2613
2614/// Represents a variable template specialization, which refers to
2615/// a variable template with a given set of template arguments.
2616///
2617/// Variable template specializations represent both explicit
2618/// specializations of variable templates, as in the example below, and
2619/// implicit instantiations of variable templates.
2620///
2621/// \code
2622/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2623///
2624/// template<>
2625/// constexpr float pi<float>; // variable template specialization pi<float>
2626/// \endcode
2627class VarTemplateSpecializationDecl : public VarDecl,
2628 public llvm::FoldingSetNode {
2629
2630 /// Structure that stores information about a variable template
2631 /// specialization that was instantiated from a variable template partial
2632 /// specialization.
2633 struct SpecializedPartialSpecialization {
2634 /// The variable template partial specialization from which this
2635 /// variable template specialization was instantiated.
2636 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2637
2638 /// The template argument list deduced for the variable template
2639 /// partial specialization itself.
2640 const TemplateArgumentList *TemplateArgs;
2641 };
2642
2643 /// The template that this specialization specializes.
2644 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2645 SpecializedTemplate;
2646
2647 /// Further info for explicit template specialization/instantiation.
2648 /// Does not apply to implicit specializations.
2649 SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
2650
2651 /// The template arguments used to describe this specialization.
2652 const TemplateArgumentList *TemplateArgs;
2653
2654 /// The point where this template was instantiated (if any).
2655 SourceLocation PointOfInstantiation;
2656
2657 /// The kind of specialization this declaration refers to.
2658 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2659 unsigned SpecializationKind : 3;
2660
2661 /// Whether this declaration is a complete definition of the
2662 /// variable template specialization. We can't otherwise tell apart
2663 /// an instantiated declaration from an instantiated definition with
2664 /// no initializer.
2665 LLVM_PREFERRED_TYPE(bool)
2666 unsigned IsCompleteDefinition : 1;
2667
2668protected:
2669 VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
2670 SourceLocation StartLoc, SourceLocation IdLoc,
2671 VarTemplateDecl *SpecializedTemplate,
2672 QualType T, TypeSourceInfo *TInfo,
2673 StorageClass S,
2674 ArrayRef<TemplateArgument> Args);
2675
2676 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2677
2678public:
2679 friend class ASTDeclReader;
2680 friend class ASTDeclWriter;
2681 friend class VarDecl;
2682
2683 static VarTemplateSpecializationDecl *
2684 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2685 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2686 TypeSourceInfo *TInfo, StorageClass S,
2687 ArrayRef<TemplateArgument> Args);
2688 static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
2689 GlobalDeclID ID);
2690
2691 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2692 bool Qualified) const override;
2693
2694 VarTemplateSpecializationDecl *getMostRecentDecl() {
2695 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2696 return cast<VarTemplateSpecializationDecl>(Val: Recent);
2697 }
2698
2699 /// Retrieve the template that this specialization specializes.
2700 VarTemplateDecl *getSpecializedTemplate() const;
2701
2702 /// Retrieve the template arguments of the variable template
2703 /// specialization.
2704 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2705
2706 /// Determine the kind of specialization that this
2707 /// declaration represents.
2708 TemplateSpecializationKind getSpecializationKind() const {
2709 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2710 }
2711
2712 bool isExplicitSpecialization() const {
2713 return getSpecializationKind() == TSK_ExplicitSpecialization;
2714 }
2715
2716 bool isClassScopeExplicitSpecialization() const {
2717 return isExplicitSpecialization() &&
2718 isa<CXXRecordDecl>(Val: getLexicalDeclContext());
2719 }
2720
2721 /// True if this declaration is an explicit specialization,
2722 /// explicit instantiation declaration, or explicit instantiation
2723 /// definition.
2724 bool isExplicitInstantiationOrSpecialization() const {
2725 return isTemplateExplicitInstantiationOrSpecialization(
2726 Kind: getTemplateSpecializationKind());
2727 }
2728
2729 void setSpecializationKind(TemplateSpecializationKind TSK) {
2730 SpecializationKind = TSK;
2731 }
2732
2733 /// Get the point of instantiation (if any), or null if none.
2734 SourceLocation getPointOfInstantiation() const {
2735 return PointOfInstantiation;
2736 }
2737
2738 void setPointOfInstantiation(SourceLocation Loc) {
2739 assert(Loc.isValid() && "point of instantiation must be valid!");
2740 PointOfInstantiation = Loc;
2741 }
2742
2743 void setCompleteDefinition() { IsCompleteDefinition = true; }
2744
2745 /// If this variable template specialization is an instantiation of
2746 /// a template (rather than an explicit specialization), return the
2747 /// variable template or variable template partial specialization from which
2748 /// it was instantiated.
2749 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2750 getInstantiatedFrom() const {
2751 if (!isTemplateInstantiation(Kind: getSpecializationKind()))
2752 return llvm::PointerUnion<VarTemplateDecl *,
2753 VarTemplatePartialSpecializationDecl *>();
2754
2755 return getSpecializedTemplateOrPartial();
2756 }
2757
2758 /// Retrieve the variable template or variable template partial
2759 /// specialization which was specialized by this.
2760 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2761 getSpecializedTemplateOrPartial() const {
2762 if (const auto *PartialSpec =
2763 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2764 return PartialSpec->PartialSpecialization;
2765
2766 return cast<VarTemplateDecl *>(Val: SpecializedTemplate);
2767 }
2768
2769 /// Retrieve the set of template arguments that should be used
2770 /// to instantiate the initializer of the variable template or variable
2771 /// template partial specialization from which this variable template
2772 /// specialization was instantiated.
2773 ///
2774 /// \returns For a variable template specialization instantiated from the
2775 /// primary template, this function will return the same template arguments
2776 /// as getTemplateArgs(). For a variable template specialization instantiated
2777 /// from a variable template partial specialization, this function will the
2778 /// return deduced template arguments for the variable template partial
2779 /// specialization itself.
2780 const TemplateArgumentList &getTemplateInstantiationArgs() const {
2781 if (const auto *PartialSpec =
2782 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2783 return *PartialSpec->TemplateArgs;
2784
2785 return getTemplateArgs();
2786 }
2787
2788 /// Note that this variable template specialization is actually an
2789 /// instantiation of the given variable template partial specialization whose
2790 /// template arguments have been deduced.
2791 void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
2792 const TemplateArgumentList *TemplateArgs) {
2793 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2794 "Already set to a variable template partial specialization!");
2795 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2796 PS->PartialSpecialization = PartialSpec;
2797 PS->TemplateArgs = TemplateArgs;
2798 SpecializedTemplate = PS;
2799 }
2800
2801 /// Note that this variable template specialization is an instantiation
2802 /// of the given variable template.
2803 void setInstantiationOf(VarTemplateDecl *TemplDecl) {
2804 assert(!isa<SpecializedPartialSpecialization *>(SpecializedTemplate) &&
2805 "Previously set to a variable template partial specialization!");
2806 SpecializedTemplate = TemplDecl;
2807 }
2808
2809 /// Retrieve the template argument list as written in the sources,
2810 /// if any.
2811 const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
2812 if (auto *Info =
2813 dyn_cast_if_present<ExplicitInstantiationInfo *>(Val: ExplicitInfo))
2814 return Info->TemplateArgsAsWritten;
2815 return cast<const ASTTemplateArgumentListInfo *>(Val: ExplicitInfo);
2816 }
2817
2818 /// Set the template argument list as written in the sources.
2819 void
2820 setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) {
2821 if (auto *Info =
2822 dyn_cast_if_present<ExplicitInstantiationInfo *>(Val&: ExplicitInfo))
2823 Info->TemplateArgsAsWritten = ArgsWritten;
2824 else
2825 ExplicitInfo = ArgsWritten;
2826 }
2827
2828 /// Set the template argument list as written in the sources.
2829 void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) {
2830 setTemplateArgsAsWritten(
2831 ASTTemplateArgumentListInfo::Create(C: getASTContext(), List: ArgsInfo));
2832 }
2833
2834 /// Gets the location of the extern keyword, if present.
2835 SourceLocation getExternKeywordLoc() const {
2836 if (auto *Info =
2837 dyn_cast_if_present<ExplicitInstantiationInfo *>(Val: ExplicitInfo))
2838 return Info->ExternKeywordLoc;
2839 return SourceLocation();
2840 }
2841
2842 /// Sets the location of the extern keyword.
2843 void setExternKeywordLoc(SourceLocation Loc);
2844
2845 /// Gets the location of the template keyword, if present.
2846 SourceLocation getTemplateKeywordLoc() const {
2847 if (auto *Info =
2848 dyn_cast_if_present<ExplicitInstantiationInfo *>(Val: ExplicitInfo))
2849 return Info->TemplateKeywordLoc;
2850 return SourceLocation();
2851 }
2852
2853 /// Sets the location of the template keyword.
2854 void setTemplateKeywordLoc(SourceLocation Loc);
2855
2856 SourceRange getSourceRange() const override LLVM_READONLY;
2857
2858 void Profile(llvm::FoldingSetNodeID &ID) const {
2859 Profile(ID, TemplateArgs: TemplateArgs->asArray(), Context: getASTContext());
2860 }
2861
2862 static void Profile(llvm::FoldingSetNodeID &ID,
2863 ArrayRef<TemplateArgument> TemplateArgs,
2864 const ASTContext &Context) {
2865 ID.AddInteger(I: TemplateArgs.size());
2866 for (const TemplateArgument &TemplateArg : TemplateArgs)
2867 TemplateArg.Profile(ID, Context);
2868 }
2869
2870 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
2871
2872 static bool classofKind(Kind K) {
2873 return K >= firstVarTemplateSpecialization &&
2874 K <= lastVarTemplateSpecialization;
2875 }
2876};
2877
2878class VarTemplatePartialSpecializationDecl
2879 : public VarTemplateSpecializationDecl {
2880 /// The list of template parameters
2881 TemplateParameterList *TemplateParams = nullptr;
2882
2883 /// The variable template partial specialization from which this
2884 /// variable template partial specialization was instantiated.
2885 ///
2886 /// The boolean value will be true to indicate that this variable template
2887 /// partial specialization was specialized at this level.
2888 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2889 InstantiatedFromMember;
2890
2891 VarTemplatePartialSpecializationDecl(
2892 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2893 SourceLocation IdLoc, TemplateParameterList *Params,
2894 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2895 StorageClass S, ArrayRef<TemplateArgument> Args);
2896
2897 VarTemplatePartialSpecializationDecl(ASTContext &Context)
2898 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2899 Context),
2900 InstantiatedFromMember(nullptr, false) {}
2901
2902 void anchor() override;
2903
2904public:
2905 friend class ASTDeclReader;
2906 friend class ASTDeclWriter;
2907
2908 static VarTemplatePartialSpecializationDecl *
2909 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2910 SourceLocation IdLoc, TemplateParameterList *Params,
2911 VarTemplateDecl *SpecializedTemplate, QualType T,
2912 TypeSourceInfo *TInfo, StorageClass S,
2913 ArrayRef<TemplateArgument> Args);
2914
2915 static VarTemplatePartialSpecializationDecl *
2916 CreateDeserialized(ASTContext &C, GlobalDeclID ID);
2917
2918 VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
2919 return cast<VarTemplatePartialSpecializationDecl>(
2920 Val: static_cast<VarTemplateSpecializationDecl *>(
2921 this)->getMostRecentDecl());
2922 }
2923
2924 /// Get the list of template parameters
2925 TemplateParameterList *getTemplateParameters() const {
2926 return TemplateParams;
2927 }
2928
2929 /// Get the template argument list of the template parameter list.
2930 ArrayRef<TemplateArgument>
2931 getInjectedTemplateArgs(const ASTContext &Context) const {
2932 return getTemplateParameters()->getInjectedTemplateArgs(Context);
2933 }
2934
2935 /// \brief All associated constraints of this partial specialization,
2936 /// including the requires clause and any constraints derived from
2937 /// constrained-parameters.
2938 ///
2939 /// The constraints in the resulting list are to be treated as if in a
2940 /// conjunction ("and").
2941 void getAssociatedConstraints(
2942 llvm::SmallVectorImpl<AssociatedConstraint> &AC) const {
2943 TemplateParams->getAssociatedConstraints(AC);
2944 }
2945
2946 bool hasAssociatedConstraints() const {
2947 return TemplateParams->hasAssociatedConstraints();
2948 }
2949
2950 /// \brief Retrieve the member variable template partial specialization from
2951 /// which this particular variable template partial specialization was
2952 /// instantiated.
2953 ///
2954 /// \code
2955 /// template<typename T>
2956 /// struct Outer {
2957 /// template<typename U> U Inner;
2958 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2959 /// };
2960 ///
2961 /// template int* Outer<float>::Inner<int*>;
2962 /// \endcode
2963 ///
2964 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2965 /// end up instantiating the partial specialization
2966 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2967 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2968 /// \c Outer<float>::Inner<U*>, this function would return
2969 /// \c Outer<T>::Inner<U*>.
2970 VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
2971 const auto *First =
2972 cast<VarTemplatePartialSpecializationDecl>(Val: getFirstDecl());
2973 return First->InstantiatedFromMember.getPointer();
2974 }
2975
2976 void
2977 setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
2978 auto *First = cast<VarTemplatePartialSpecializationDecl>(Val: getFirstDecl());
2979 First->InstantiatedFromMember.setPointer(PartialSpec);
2980 }
2981
2982 /// Determines whether this variable template partial specialization
2983 /// was a specialization of a member partial specialization.
2984 ///
2985 /// In the following example, the member template partial specialization
2986 /// \c X<int>::Inner<T*> is a member specialization.
2987 ///
2988 /// \code
2989 /// template<typename T>
2990 /// struct X {
2991 /// template<typename U> U Inner;
2992 /// template<typename U> U* Inner<U*> = (U*)(0);
2993 /// };
2994 ///
2995 /// template<> template<typename T>
2996 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2997 /// \endcode
2998 bool isMemberSpecialization() const {
2999 const auto *First =
3000 cast<VarTemplatePartialSpecializationDecl>(Val: getFirstDecl());
3001 return First->InstantiatedFromMember.getInt();
3002 }
3003
3004 /// Note that this member template is a specialization.
3005 /// A partial specialization may be a member specialization even if it is not
3006 /// an instantiation of a member partial specialization.
3007 void setMemberSpecialization() {
3008 auto *First = cast<VarTemplatePartialSpecializationDecl>(Val: getFirstDecl());
3009 return First->InstantiatedFromMember.setInt(true);
3010 }
3011
3012 SourceRange getSourceRange() const override LLVM_READONLY;
3013
3014 void Profile(llvm::FoldingSetNodeID &ID) const {
3015 Profile(ID, TemplateArgs: getTemplateArgs().asArray(), TPL: getTemplateParameters(),
3016 Context: getASTContext());
3017 }
3018
3019 static void
3020 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3021 TemplateParameterList *TPL, const ASTContext &Context);
3022
3023 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
3024
3025 static bool classofKind(Kind K) {
3026 return K == VarTemplatePartialSpecialization;
3027 }
3028};
3029
3030/// Declaration of a variable template.
3031class VarTemplateDecl : public RedeclarableTemplateDecl {
3032protected:
3033 /// Data that is common to all of the declarations of a given
3034 /// variable template.
3035 struct Common : CommonBase {
3036 /// The variable template specializations for this variable
3037 /// template, including explicit specializations and instantiations.
3038 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3039
3040 /// The variable template partial specializations for this variable
3041 /// template.
3042 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3043 PartialSpecializations;
3044
3045 Common() = default;
3046 };
3047
3048 /// Retrieve the set of specializations of this variable template.
3049 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3050 getSpecializations() const;
3051
3052 /// Retrieve the set of partial specializations of this class
3053 /// template.
3054 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3055 getPartialSpecializations() const;
3056
3057 VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
3058 DeclarationName Name, TemplateParameterList *Params,
3059 NamedDecl *Decl)
3060 : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
3061
3062 CommonBase *newCommon(ASTContext &C) const override;
3063
3064 Common *getCommonPtr() const {
3065 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3066 }
3067
3068public:
3069 friend class ASTDeclReader;
3070 friend class ASTDeclWriter;
3071
3072 /// Load any lazily-loaded specializations from the external source.
3073 void LoadLazySpecializations(bool OnlyPartial = false) const;
3074
3075 /// Get the underlying variable declarations of the template.
3076 VarDecl *getTemplatedDecl() const {
3077 return static_cast<VarDecl *>(TemplatedDecl);
3078 }
3079
3080 /// Returns whether this template declaration defines the primary
3081 /// variable pattern.
3082 bool isThisDeclarationADefinition() const {
3083 return getTemplatedDecl()->isThisDeclarationADefinition();
3084 }
3085
3086 VarTemplateDecl *getDefinition();
3087
3088 /// Create a variable template node.
3089 static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
3090 SourceLocation L, DeclarationName Name,
3091 TemplateParameterList *Params,
3092 VarDecl *Decl);
3093
3094 /// Create an empty variable template node.
3095 static VarTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
3096
3097 /// Return the specialization with the provided arguments if it exists,
3098 /// otherwise return the insertion point.
3099 VarTemplateSpecializationDecl *
3100 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3101
3102 /// Insert the specified specialization knowing that it is not already
3103 /// in. InsertPos must be obtained from findSpecialization.
3104 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3105
3106 VarTemplateDecl *getCanonicalDecl() override {
3107 return cast<VarTemplateDecl>(Val: RedeclarableTemplateDecl::getCanonicalDecl());
3108 }
3109 const VarTemplateDecl *getCanonicalDecl() const {
3110 return cast<VarTemplateDecl>(Val: RedeclarableTemplateDecl::getCanonicalDecl());
3111 }
3112
3113 /// Retrieve the previous declaration of this variable template, or
3114 /// nullptr if no such declaration exists.
3115 VarTemplateDecl *getPreviousDecl() {
3116 return cast_or_null<VarTemplateDecl>(
3117 Val: static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3118 }
3119 const VarTemplateDecl *getPreviousDecl() const {
3120 return cast_or_null<VarTemplateDecl>(
3121 Val: static_cast<const RedeclarableTemplateDecl *>(
3122 this)->getPreviousDecl());
3123 }
3124
3125 VarTemplateDecl *getMostRecentDecl() {
3126 return cast<VarTemplateDecl>(
3127 Val: static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
3128 }
3129 const VarTemplateDecl *getMostRecentDecl() const {
3130 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3131 }
3132
3133 VarTemplateDecl *getInstantiatedFromMemberTemplate() const {
3134 return cast_or_null<VarTemplateDecl>(
3135 Val: RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
3136 }
3137
3138 /// Return the partial specialization with the provided arguments if it
3139 /// exists, otherwise return the insertion point.
3140 VarTemplatePartialSpecializationDecl *
3141 findPartialSpecialization(ArrayRef<TemplateArgument> Args,
3142 TemplateParameterList *TPL, void *&InsertPos);
3143
3144 /// Insert the specified partial specialization knowing that it is not
3145 /// already in. InsertPos must be obtained from findPartialSpecialization.
3146 void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
3147 void *InsertPos);
3148
3149 /// Retrieve the partial specializations as an ordered list.
3150 void getPartialSpecializations(
3151 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const;
3152
3153 /// Find a variable template partial specialization which was
3154 /// instantiated
3155 /// from the given member partial specialization.
3156 ///
3157 /// \param D a member variable template partial specialization.
3158 ///
3159 /// \returns the variable template partial specialization which was
3160 /// instantiated
3161 /// from the given member partial specialization, or nullptr if no such
3162 /// partial specialization exists.
3163 VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
3164 VarTemplatePartialSpecializationDecl *D);
3165
3166 using spec_iterator = SpecIterator<VarTemplateSpecializationDecl>;
3167 using spec_range = llvm::iterator_range<spec_iterator>;
3168
3169 spec_range specializations() const {
3170 return spec_range(spec_begin(), spec_end());
3171 }
3172
3173 spec_iterator spec_begin() const {
3174 return makeSpecIterator(Specs&: getSpecializations(), isEnd: false);
3175 }
3176
3177 spec_iterator spec_end() const {
3178 return makeSpecIterator(Specs&: getSpecializations(), isEnd: true);
3179 }
3180
3181 // Implement isa/cast/dyncast support
3182 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
3183 static bool classofKind(Kind K) { return K == VarTemplate; }
3184};
3185
3186/// Declaration of a C++20 concept.
3187class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3188protected:
3189 Expr *ConstraintExpr;
3190
3191 ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
3192 TemplateParameterList *Params, Expr *ConstraintExpr)
3193 : TemplateDecl(Concept, DC, L, Name, Params),
3194 ConstraintExpr(ConstraintExpr) {};
3195public:
3196 static ConceptDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
3197 DeclarationName Name,
3198 TemplateParameterList *Params,
3199 Expr *ConstraintExpr = nullptr);
3200 static ConceptDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
3201
3202 Expr *getConstraintExpr() const {
3203 return ConstraintExpr;
3204 }
3205
3206 bool hasDefinition() const { return ConstraintExpr != nullptr; }
3207
3208 void setDefinition(Expr *E) { ConstraintExpr = E; }
3209
3210 SourceRange getSourceRange() const override LLVM_READONLY {
3211 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3212 ConstraintExpr ? ConstraintExpr->getEndLoc()
3213 : SourceLocation());
3214 }
3215
3216 bool isTypeConcept() const {
3217 return isa<TemplateTypeParmDecl>(Val: getTemplateParameters()->getParam(Idx: 0));
3218 }
3219
3220 ConceptDecl *getCanonicalDecl() override {
3221 return cast<ConceptDecl>(Val: getPrimaryMergedDecl(D: this));
3222 }
3223 const ConceptDecl *getCanonicalDecl() const {
3224 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3225 }
3226
3227 // Implement isa/cast/dyncast/etc.
3228 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
3229 static bool classofKind(Kind K) { return K == Concept; }
3230
3231 friend class ASTReader;
3232 friend class ASTDeclReader;
3233 friend class ASTDeclWriter;
3234};
3235
3236// An implementation detail of ConceptSpecialicationExpr that holds the template
3237// arguments, so we can later use this to reconstitute the template arguments
3238// during constraint checking.
3239class ImplicitConceptSpecializationDecl final
3240 : public Decl,
3241 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3242 TemplateArgument> {
3243 unsigned NumTemplateArgs;
3244
3245 ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL,
3246 ArrayRef<TemplateArgument> ConvertedArgs);
3247 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3248
3249public:
3250 static ImplicitConceptSpecializationDecl *
3251 Create(const ASTContext &C, DeclContext *DC, SourceLocation SL,
3252 ArrayRef<TemplateArgument> ConvertedArgs);
3253 static ImplicitConceptSpecializationDecl *
3254 CreateDeserialized(const ASTContext &C, GlobalDeclID ID,
3255 unsigned NumTemplateArgs);
3256
3257 ArrayRef<TemplateArgument> getTemplateArguments() const {
3258 return getTrailingObjects(N: NumTemplateArgs);
3259 }
3260 void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
3261
3262 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3263 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
3264
3265 friend TrailingObjects;
3266 friend class ASTDeclReader;
3267};
3268
3269/// A template parameter object.
3270///
3271/// Template parameter objects represent values of class type used as template
3272/// arguments. There is one template parameter object for each such distinct
3273/// value used as a template argument across the program.
3274///
3275/// \code
3276/// struct A { int x, y; };
3277/// template<A> struct S;
3278/// S<A{1, 2}> s1;
3279/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3280/// \endcode
3281class TemplateParamObjectDecl : public ValueDecl,
3282 public Mergeable<TemplateParamObjectDecl>,
3283 public llvm::FoldingSetNode {
3284private:
3285 /// The value of this template parameter object.
3286 APValue Value;
3287
3288 TemplateParamObjectDecl(DeclContext *DC, QualType T, const APValue &V)
3289 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3290 T),
3291 Value(V) {}
3292
3293 static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
3294 const APValue &V);
3295 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3296 GlobalDeclID ID);
3297
3298 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3299 /// create these.
3300 friend class ASTContext;
3301 friend class ASTReader;
3302 friend class ASTDeclReader;
3303
3304public:
3305 /// Print this template parameter object in a human-readable format.
3306 void printName(llvm::raw_ostream &OS,
3307 const PrintingPolicy &Policy) const override;
3308
3309 /// Print this object as an equivalent expression.
3310 void printAsExpr(llvm::raw_ostream &OS) const;
3311 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3312
3313 /// Print this object as an initializer suitable for a variable of the
3314 /// object's type.
3315 void printAsInit(llvm::raw_ostream &OS) const;
3316 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3317
3318 const APValue &getValue() const { return Value; }
3319
3320 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3321 const APValue &V) {
3322 ID.AddPointer(Ptr: T.getCanonicalType().getAsOpaquePtr());
3323 V.Profile(ID);
3324 }
3325 void Profile(llvm::FoldingSetNodeID &ID) {
3326 Profile(ID, T: getType(), V: getValue());
3327 }
3328
3329 TemplateParamObjectDecl *getCanonicalDecl() override {
3330 return getFirstDecl();
3331 }
3332 const TemplateParamObjectDecl *getCanonicalDecl() const {
3333 return getFirstDecl();
3334 }
3335
3336 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
3337 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3338};
3339
3340/// Represents a C++26 expansion statement declaration.
3341///
3342/// This is a bit of a hack, since expansion statements shouldn't really be
3343/// 'declarations' per se (they don't declare anything). Nevertheless, we *do*
3344/// need them to be declaration *contexts*, because the DeclContext is used to
3345/// compute the 'template depth' of entities enclosed therein. In particular,
3346/// the 'template depth' is used to find instantiations of parameter variables.
3347/// A lambda enclosed within an expansion statement cannot compute its
3348/// template depth without a pointer to the enclosing expansion statement.
3349///
3350/// For the remainder of this comment, let 'expanding' an expansion statement
3351/// refer to the process of performing template substitution on its body N
3352/// times, where N is the expansion size (how this size is determined depends on
3353/// the kind of expansion statement); by contrast we may sometimes 'instantiate'
3354/// an expansion statement (because it happens to be in a template). This is
3355/// just regular template instantiation.
3356///
3357/// This node contains a 'CXXExpansionStmtPattern' as well as a
3358/// 'CXXExpansionStmtInstantiation'. These two members correspond to
3359/// distinct representations of the expansion statement: the former is used
3360/// prior to expansion and contains all the parts needed to perform expansion;
3361/// the latter holds the expanded/desugared AST nodes that result from the
3362/// expansion.
3363///
3364/// Additionally, there is a 'NonTypeTemplateParmDecl', which is a template
3365/// parameter that serves as the expansion index, e.g. during the N-th
3366/// expansion, it is set to 'N'. See the documentation of
3367/// 'CXXExpansionStmtPattern', for more information on how this is used.
3368///
3369/// After expansion, the 'CXXExpansionStmtPattern' is no longer updated and left
3370/// as-is; this also means that, if an already-expanded expansion statement is
3371/// inside a template, and that template is then instantiated, the
3372/// 'CXXExpansionStmtPattern' is *not* instantiated; only the
3373/// 'CXXExpansionStmtInstantiation' is. The latter is also what's used for
3374/// codegen and constant evaluation.
3375///
3376/// There are different kinds of expansion statements; see the comment on
3377/// 'CXXExpansionStmtPattern' for more information.
3378///
3379/// As an example, if the user writes the following expansion statement:
3380/// \verbatim
3381/// std::tuple<int, int, int> a{1, 2, 3};
3382/// template for (auto x : a) {
3383/// // ...
3384/// }
3385/// \endverbatim
3386///
3387/// The 'CXXExpansionStmtPattern' of this particular 'CXXExpansionStmtDecl'
3388/// stores, amongst other things, the declaration of the variable 'x' as well
3389/// as the expansion-initializer 'a'.
3390///
3391/// After expansion, we end up with a 'CXXExpansionStmtInstantiation' that
3392/// is *equivalent* to the AST shown below. Note that only the inner '{}' (i.e.
3393/// those marked as 'Actual "CompoundStmt"' below) are actually present as
3394/// 'CompoundStmt's in the AST; the outer braces that wrap everything do *not*
3395/// correspond to an actual 'CompoundStmt' and are implicit in the sense that we
3396/// simply push a scope when evaluating or emitting IR for a
3397/// 'CXXExpansionStmtInstantiation'.
3398///
3399/// \verbatim
3400/// { // Not actually present in the AST.
3401/// auto [__u0, __u1, __u2] = a;
3402/// { // Actual 'CompoundStmt'.
3403/// auto x = __u0;
3404/// // ...
3405/// }
3406/// { // Actual 'CompoundStmt'.
3407/// auto x = __u1;
3408/// // ...
3409/// }
3410/// { // Actual 'CompoundStmt'.
3411/// auto x = __u2;
3412/// // ...
3413/// }
3414/// }
3415/// \endverbatim
3416///
3417/// See the documentation around 'CXXExpansionStmtInstantiation' for more notes
3418/// as to why this node exist and how it is used.
3419///
3420/// \see CXXExpansionStmtPattern
3421/// \see CXXExpansionStmtInstantiation
3422class CXXExpansionStmtDecl : public Decl, public DeclContext {
3423 CXXExpansionStmtPattern *Pattern = nullptr;
3424 NonTypeTemplateParmDecl *IndexNTTP = nullptr;
3425 CXXExpansionStmtInstantiation *Instantiations = nullptr;
3426
3427 CXXExpansionStmtDecl(DeclContext *DC, SourceLocation Loc,
3428 NonTypeTemplateParmDecl *NTTP);
3429
3430public:
3431 friend class ASTDeclReader;
3432
3433 static CXXExpansionStmtDecl *Create(ASTContext &C, DeclContext *DC,
3434 SourceLocation Loc,
3435 NonTypeTemplateParmDecl *NTTP);
3436 static CXXExpansionStmtDecl *CreateDeserialized(ASTContext &C,
3437 GlobalDeclID ID);
3438
3439 CXXExpansionStmtPattern *getExpansionPattern() { return Pattern; }
3440 const CXXExpansionStmtPattern *getExpansionPattern() const { return Pattern; }
3441 void setExpansionPattern(CXXExpansionStmtPattern *S) { Pattern = S; }
3442
3443 CXXExpansionStmtInstantiation *getInstantiations() { return Instantiations; }
3444 const CXXExpansionStmtInstantiation *getInstantiations() const {
3445 return Instantiations;
3446 }
3447
3448 void setInstantiations(CXXExpansionStmtInstantiation *S) {
3449 Instantiations = S;
3450 }
3451
3452 NonTypeTemplateParmDecl *getIndexTemplateParm() { return IndexNTTP; }
3453 const NonTypeTemplateParmDecl *getIndexTemplateParm() const {
3454 return IndexNTTP;
3455 }
3456
3457 SourceRange getSourceRange() const override LLVM_READONLY;
3458
3459 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
3460 static bool classofKind(Kind K) { return K == CXXExpansionStmt; }
3461};
3462
3463inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
3464 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3465 return PD;
3466 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3467 return PD;
3468 return cast<TemplateTemplateParmDecl *>(Val&: P);
3469}
3470
3471inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
3472 auto *TD = dyn_cast<TemplateDecl>(Val: D);
3473 return TD && (isa<ClassTemplateDecl>(Val: TD) ||
3474 isa<ClassTemplatePartialSpecializationDecl>(Val: TD) ||
3475 isa<TypeAliasTemplateDecl>(Val: TD) ||
3476 [&]() {
3477 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Val: TD))
3478 return TTP->templateParameterKind() == TNK_Type_template;
3479 return false;
3480 }())
3481 ? TD
3482 : nullptr;
3483}
3484
3485/// Check whether the template parameter is a pack expansion, and if so,
3486/// determine the number of parameters produced by that expansion. For instance:
3487///
3488/// \code
3489/// template<typename ...Ts> struct A {
3490/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3491/// };
3492/// \endcode
3493///
3494/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3495/// is not a pack expansion, so returns an empty Optional.
3496inline UnsignedOrNone getExpandedPackSize(const NamedDecl *Param) {
3497 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Val: Param)) {
3498 if (UnsignedOrNone Num = TTP->getNumExpansionParameters())
3499 return Num;
3500 }
3501
3502 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Val: Param)) {
3503 if (NTTP->isExpandedParameterPack())
3504 return NTTP->getNumExpansionTypes();
3505 }
3506
3507 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Val: Param)) {
3508 if (TTP->isExpandedParameterPack())
3509 return TTP->getNumExpansionTemplateParameters();
3510 }
3511
3512 return std::nullopt;
3513}
3514
3515/// Internal helper used by Subst* nodes to retrieve a parameter from the
3516/// AssociatedDecl, and the template argument substituted into it, if any.
3517std::tuple<NamedDecl *, TemplateArgument>
3518getReplacedTemplateParameter(Decl *D, unsigned Index);
3519
3520/// If we have a 'templated' declaration for a template, adjust 'D' to
3521/// refer to the actual template.
3522/// If we have an implicit instantiation, adjust 'D' to refer to template.
3523const Decl &adjustDeclToTemplate(const Decl &D);
3524
3525/// Represents an explicit instantiation of a template entity in source code.
3526///
3527/// \code
3528/// template void ns::foo<int>(int); // function template
3529/// extern template struct ns::S<int>; // class template (extern)
3530/// template int ns::bar<int>; // variable template
3531/// template void ns::S<int>::method(int); // member function
3532/// \endcode
3533class ExplicitInstantiationDecl final
3534 : public Decl,
3535 private llvm::TrailingObjects<ExplicitInstantiationDecl,
3536 NestedNameSpecifierLoc,
3537 const ASTTemplateArgumentListInfo *> {
3538 friend class ASTDeclReader;
3539 friend class ASTDeclWriter;
3540 friend TrailingObjects;
3541
3542 /// The underlying specialization (low 3 bits: TSK).
3543 llvm::PointerIntPair<NamedDecl *, 3, unsigned> SpecAndTSK;
3544
3545 /// TypeSourceInfo (low 2 bits: trailing-object flags).
3546 /// Always non-null after construction.
3547 /// - Class templates: TemplateSpecializationTypeLoc encoding keyword,
3548 /// qualifier, template-name, and argument locations.
3549 /// - Nested classes: TagTypeLoc encoding keyword, qualifier, and name.
3550 /// - Function / variable templates: the declared type.
3551 llvm::PointerIntPair<TypeSourceInfo *, 2, unsigned> TypeAndFlags;
3552
3553 /// Location of the 'extern' keyword (invalid if not extern template).
3554 SourceLocation ExternLoc;
3555
3556 /// Location of the entity name (e.g., 'foo' in 'template void
3557 /// ns::foo<int>(int)').
3558 SourceLocation NameLoc;
3559
3560 enum TrailingFlags : unsigned {
3561 HasQualifierFlag = 1,
3562 HasArgsAsWrittenFlag = 2,
3563 };
3564
3565 size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const {
3566 return hasTrailingQualifier() ? 1 : 0;
3567 }
3568
3569 /// For class templates / nested classes, returns the TypeLoc encoding the
3570 /// entity (TemplateSpecializationTypeLoc or TagTypeLoc). For function /
3571 /// variable templates -- where TypeSourceInfo holds the declared type
3572 /// rather than the entity -- returns std::nullopt.
3573 std::optional<TypeLoc> getClassTypeLoc() const {
3574 if (!isa<RecordDecl>(Val: getSpecialization()))
3575 return std::nullopt;
3576 if (auto *TSI = TypeAndFlags.getPointer())
3577 return TSI->getTypeLoc();
3578 return std::nullopt;
3579 }
3580
3581 /// Raw TypeSourceInfo pointer, needed by the serializer.
3582 TypeSourceInfo *getRawTypeSourceInfo() const {
3583 return TypeAndFlags.getPointer();
3584 }
3585
3586 /// Returns the trailing ASTTemplateArgumentListInfo pointer, or null.
3587 const ASTTemplateArgumentListInfo *getTrailingArgsInfo() const {
3588 if (!hasTrailingArgsAsWritten())
3589 return nullptr;
3590 return *getTrailingObjects<const ASTTemplateArgumentListInfo *>();
3591 }
3592
3593 ExplicitInstantiationDecl(
3594 DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc,
3595 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
3596 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
3597 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK);
3598
3599 ExplicitInstantiationDecl(EmptyShell Empty)
3600 : Decl(ExplicitInstantiation, Empty) {}
3601
3602public:
3603 static ExplicitInstantiationDecl *
3604 Create(ASTContext &C, DeclContext *DC, NamedDecl *Specialization,
3605 SourceLocation ExternLoc, SourceLocation TemplateLoc,
3606 NestedNameSpecifierLoc QualifierLoc,
3607 const ASTTemplateArgumentListInfo *ArgsAsWritten,
3608 SourceLocation NameLoc, TypeSourceInfo *TypeAsWritten,
3609 TemplateSpecializationKind TSK);
3610
3611 static ExplicitInstantiationDecl *
3612 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags);
3613
3614 NamedDecl *getSpecialization() const { return SpecAndTSK.getPointer(); }
3615
3616 SourceRange getSourceRange() const override LLVM_READONLY;
3617 SourceLocation getEndLoc() const LLVM_READONLY;
3618
3619 SourceLocation getExternLoc() const { return ExternLoc; }
3620 SourceLocation getTemplateLoc() const { return getLocation(); }
3621 SourceLocation getNameLoc() const { return NameLoc; }
3622
3623 /// The tag keyword (struct/class/union) location for class templates /
3624 /// nested classes; invalid for function / variable templates.
3625 SourceLocation getTagKWLoc() const;
3626
3627 bool hasTrailingQualifier() const {
3628 return TypeAndFlags.getInt() & HasQualifierFlag;
3629 }
3630 bool hasTrailingArgsAsWritten() const {
3631 return TypeAndFlags.getInt() & HasArgsAsWrittenFlag;
3632 }
3633
3634 /// Returns the qualifier regardless of where it is stored.
3635 /// For class templates / nested classes, extracted from the class TypeLoc;
3636 /// for function / variable templates, from a trailing object.
3637 NestedNameSpecifierLoc getQualifierLoc() const;
3638
3639 /// Returns the number of explicit template arguments, or std::nullopt if
3640 /// this entity has no template argument list (e.g., nested classes).
3641 std::optional<unsigned> getNumTemplateArgs() const;
3642 TemplateArgumentLoc getTemplateArg(unsigned I) const;
3643 SourceLocation getTemplateArgsLAngleLoc() const;
3644 SourceLocation getTemplateArgsRAngleLoc() const;
3645
3646 /// The declared type (return type or variable type) for function / variable
3647 /// templates. Null for class templates and nested classes.
3648 TypeSourceInfo *getTypeAsWritten() const;
3649
3650 TemplateSpecializationKind getTemplateSpecializationKind() const {
3651 return static_cast<TemplateSpecializationKind>(SpecAndTSK.getInt());
3652 }
3653
3654 bool isExternTemplate() const { return ExternLoc.isValid(); }
3655
3656 static bool classof(const Decl *D) { return classofKind(K: D->getKind()); }
3657 static bool classofKind(Kind K) { return K == ExplicitInstantiation; }
3658};
3659
3660} // namespace clang
3661
3662#endif // LLVM_CLANG_AST_DECLTEMPLATE_H
3663