clang 19.0.0git
DeclTemplate.h
Go to the documentation of this file.
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
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclBase.h"
21#include "clang/AST/DeclCXX.h"
25#include "clang/AST/Type.h"
26#include "clang/Basic/LLVM.h"
29#include "llvm/ADT/ArrayRef.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/PointerIntPair.h"
32#include "llvm/ADT/PointerUnion.h"
33#include "llvm/ADT/iterator.h"
34#include "llvm/ADT/iterator_range.h"
35#include "llvm/Support/Casting.h"
36#include "llvm/Support/Compiler.h"
37#include "llvm/Support/TrailingObjects.h"
38#include <cassert>
39#include <cstddef>
40#include <cstdint>
41#include <iterator>
42#include <optional>
43#include <utility>
44
45namespace clang {
46
48class ClassTemplateDecl;
49class ClassTemplatePartialSpecializationDecl;
50class Expr;
51class FunctionTemplateDecl;
52class IdentifierInfo;
53class NonTypeTemplateParmDecl;
54class TemplateDecl;
55class TemplateTemplateParmDecl;
56class TemplateTypeParmDecl;
57class ConceptDecl;
58class UnresolvedSetImpl;
59class VarTemplateDecl;
60class VarTemplatePartialSpecializationDecl;
61
62/// Stores a template parameter of any kind.
64 llvm::PointerUnion<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *,
66
68
69/// Stores a list of template parameters for a TemplateDecl and its
70/// derived classes.
72 : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *,
73 Expr *> {
74 /// The location of the 'template' keyword.
75 SourceLocation TemplateLoc;
76
77 /// The locations of the '<' and '>' angle brackets.
78 SourceLocation LAngleLoc, RAngleLoc;
79
80 /// The number of template parameters in this template
81 /// parameter list.
82 unsigned NumParams : 29;
83
84 /// Whether this template parameter list contains an unexpanded parameter
85 /// pack.
86 LLVM_PREFERRED_TYPE(bool)
87 unsigned ContainsUnexpandedParameterPack : 1;
88
89 /// Whether this template parameter list has a requires clause.
90 LLVM_PREFERRED_TYPE(bool)
91 unsigned HasRequiresClause : 1;
92
93 /// Whether any of the template parameters has constrained-parameter
94 /// constraint-expression.
95 LLVM_PREFERRED_TYPE(bool)
96 unsigned HasConstrainedParameters : 1;
97
98protected:
100 SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
101 SourceLocation RAngleLoc, Expr *RequiresClause);
102
103 size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
104 return NumParams;
105 }
106
107 size_t numTrailingObjects(OverloadToken<Expr *>) const {
108 return HasRequiresClause ? 1 : 0;
109 }
110
111public:
112 template <size_t N, bool HasRequiresClause>
115
117 SourceLocation TemplateLoc,
118 SourceLocation LAngleLoc,
120 SourceLocation RAngleLoc,
121 Expr *RequiresClause);
122
123 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const;
124
125 /// Iterates through the template parameters in this list.
126 using iterator = NamedDecl **;
127
128 /// Iterates through the template parameters in this list.
129 using const_iterator = NamedDecl * const *;
130
131 iterator begin() { return getTrailingObjects<NamedDecl *>(); }
132 const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
133 iterator end() { return begin() + NumParams; }
134 const_iterator end() const { return begin() + NumParams; }
135
136 unsigned size() const { return NumParams; }
137 bool empty() const { return NumParams == 0; }
138
141 return llvm::ArrayRef(begin(), size());
142 }
143
144 NamedDecl* getParam(unsigned Idx) {
145 assert(Idx < size() && "Template parameter index out-of-range");
146 return begin()[Idx];
147 }
148 const NamedDecl* getParam(unsigned Idx) const {
149 assert(Idx < size() && "Template parameter index out-of-range");
150 return begin()[Idx];
151 }
152
153 /// Returns the minimum number of arguments needed to form a
154 /// template specialization.
155 ///
156 /// This may be fewer than the number of template parameters, if some of
157 /// the parameters have default arguments or if there is a parameter pack.
158 unsigned getMinRequiredArguments() const;
159
160 /// Get the depth of this template parameter list in the set of
161 /// template parameter lists.
162 ///
163 /// The first template parameter list in a declaration will have depth 0,
164 /// the second template parameter list will have depth 1, etc.
165 unsigned getDepth() const;
166
167 /// Determine whether this template parameter list contains an
168 /// unexpanded parameter pack.
170
171 /// Determine whether this template parameter list contains a parameter pack.
172 bool hasParameterPack() const {
173 for (const NamedDecl *P : asArray())
174 if (P->isParameterPack())
175 return true;
176 return false;
177 }
178
179 /// The constraint-expression of the associated requires-clause.
181 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
182 }
183
184 /// The constraint-expression of the associated requires-clause.
185 const Expr *getRequiresClause() const {
186 return HasRequiresClause ? getTrailingObjects<Expr *>()[0] : nullptr;
187 }
188
189 /// \brief All associated constraints derived from this template parameter
190 /// list, including the requires clause and any constraints derived from
191 /// constrained-parameters.
192 ///
193 /// The constraints in the resulting list are to be treated as if in a
194 /// conjunction ("and").
196
198
199 SourceLocation getTemplateLoc() const { return TemplateLoc; }
200 SourceLocation getLAngleLoc() const { return LAngleLoc; }
201 SourceLocation getRAngleLoc() const { return RAngleLoc; }
202
203 SourceRange getSourceRange() const LLVM_READONLY {
204 return SourceRange(TemplateLoc, RAngleLoc);
205 }
206
207 void print(raw_ostream &Out, const ASTContext &Context,
208 bool OmitTemplateKW = false) const;
209 void print(raw_ostream &Out, const ASTContext &Context,
210 const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
211
213 const TemplateParameterList *TPL,
214 unsigned Idx);
215};
216
217/// Stores a list of template parameters and the associated
218/// requires-clause (if any) for a TemplateDecl and its derived classes.
219/// Suitable for creating on the stack.
220template <size_t N, bool HasRequiresClause>
222 : public TemplateParameterList::FixedSizeStorageOwner {
223 typename TemplateParameterList::FixedSizeStorage<
224 NamedDecl *, Expr *>::with_counts<
225 N, HasRequiresClause ? 1u : 0u
226 >::type storage;
227
228public:
230 SourceLocation TemplateLoc,
231 SourceLocation LAngleLoc,
233 SourceLocation RAngleLoc,
234 Expr *RequiresClause)
235 : FixedSizeStorageOwner(
236 (assert(N == Params.size()),
237 assert(HasRequiresClause == (RequiresClause != nullptr)),
238 new (static_cast<void *>(&storage)) TemplateParameterList(C,
239 TemplateLoc, LAngleLoc, Params, RAngleLoc, RequiresClause))) {}
240};
241
242/// A template argument list.
244 : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
245 /// The number of template arguments in this template
246 /// argument list.
247 unsigned NumArguments;
248
249 // Constructs an instance with an internal Argument list, containing
250 // a copy of the Args array. (Called by CreateCopy)
252
253public:
255
258
259 /// Create a new template argument list that copies the given set of
260 /// template arguments.
263
264 /// Retrieve the template argument at a given index.
265 const TemplateArgument &get(unsigned Idx) const {
266 assert(Idx < NumArguments && "Invalid template argument index");
267 return data()[Idx];
268 }
269
270 /// Retrieve the template argument at a given index.
271 const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
272
273 /// Produce this as an array ref.
275 return llvm::ArrayRef(data(), size());
276 }
277
278 /// Retrieve the number of template arguments in this
279 /// template argument list.
280 unsigned size() const { return NumArguments; }
281
282 /// Retrieve a pointer to the template argument list.
283 const TemplateArgument *data() const {
284 return getTrailingObjects<TemplateArgument>();
285 }
286};
287
288void *allocateDefaultArgStorageChain(const ASTContext &C);
289
290/// Storage for a default argument. This is conceptually either empty, or an
291/// argument value, or a pointer to a previous declaration that had a default
292/// argument.
293///
294/// However, this is complicated by modules: while we require all the default
295/// arguments for a template to be equivalent, there may be more than one, and
296/// we need to track all the originating parameters to determine if the default
297/// argument is visible.
298template<typename ParmDecl, typename ArgType>
300 /// Storage for both the value *and* another parameter from which we inherit
301 /// the default argument. This is used when multiple default arguments for a
302 /// parameter are merged together from different modules.
303 struct Chain {
304 ParmDecl *PrevDeclWithDefaultArg;
305 ArgType Value;
306 };
307 static_assert(sizeof(Chain) == sizeof(void *) * 2,
308 "non-pointer argument type?");
309
310 llvm::PointerUnion<ArgType, ParmDecl*, Chain*> ValueOrInherited;
311
312 static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
313 const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
314 if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl *>())
315 Parm = Prev;
316 assert(!Parm->getDefaultArgStorage()
317 .ValueOrInherited.template is<ParmDecl *>() &&
318 "should only be one level of indirection");
319 return Parm;
320 }
321
322public:
323 DefaultArgStorage() : ValueOrInherited(ArgType()) {}
324
325 /// Determine whether there is a default argument for this parameter.
326 bool isSet() const { return !ValueOrInherited.isNull(); }
327
328 /// Determine whether the default argument for this parameter was inherited
329 /// from a previous declaration of the same entity.
330 bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
331
332 /// Get the default argument's value. This does not consider whether the
333 /// default argument is visible.
334 ArgType get() const {
335 const DefaultArgStorage *Storage = this;
336 if (const auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl *>())
337 Storage = &Prev->getDefaultArgStorage();
338 if (const auto *C = Storage->ValueOrInherited.template dyn_cast<Chain *>())
339 return C->Value;
340 return Storage->ValueOrInherited.template get<ArgType>();
341 }
342
343 /// Get the parameter from which we inherit the default argument, if any.
344 /// This is the parameter on which the default argument was actually written.
345 const ParmDecl *getInheritedFrom() const {
346 if (const auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>())
347 return D;
348 if (const auto *C = ValueOrInherited.template dyn_cast<Chain *>())
349 return C->PrevDeclWithDefaultArg;
350 return nullptr;
351 }
352
353 /// Set the default argument.
354 void set(ArgType Arg) {
355 assert(!isSet() && "default argument already set");
356 ValueOrInherited = Arg;
357 }
358
359 /// Set that the default argument was inherited from another parameter.
360 void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) {
361 InheritedFrom = getParmOwningDefaultArg(InheritedFrom);
362 if (!isSet())
363 ValueOrInherited = InheritedFrom;
364 else if ([[maybe_unused]] auto *D =
365 ValueOrInherited.template dyn_cast<ParmDecl *>()) {
366 assert(C.isSameDefaultTemplateArgument(D, InheritedFrom));
367 ValueOrInherited =
368 new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()};
369 } else if (auto *Inherited =
370 ValueOrInherited.template dyn_cast<Chain *>()) {
371 assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg,
372 InheritedFrom));
373 Inherited->PrevDeclWithDefaultArg = InheritedFrom;
374 } else
375 ValueOrInherited = new (allocateDefaultArgStorageChain(C))
376 Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
377 }
378
379 /// Remove the default argument, even if it was inherited.
380 void clear() {
381 ValueOrInherited = ArgType();
382 }
383};
384
385//===----------------------------------------------------------------------===//
386// Kinds of Templates
387//===----------------------------------------------------------------------===//
388
389/// \brief The base class of all kinds of template declarations (e.g.,
390/// class, function, etc.).
391///
392/// The TemplateDecl class stores the list of template parameters and a
393/// reference to the templated scoped declaration: the underlying AST node.
394class TemplateDecl : public NamedDecl {
395 void anchor() override;
396
397protected:
398 // Construct a template decl with name, parameters, and templated element.
401
402 // Construct a template decl with the given name and parameters.
403 // Used when there is no templated element (e.g., for tt-params).
405 TemplateParameterList *Params)
406 : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
407
408public:
409 friend class ASTDeclReader;
410 friend class ASTDeclWriter;
411
412 /// Get the list of template parameters
414 return TemplateParams;
415 }
416
417 /// \brief Get the total constraint-expression associated with this template,
418 /// including constraint-expressions derived from the requires-clause,
419 /// trailing requires-clause (for functions and methods) and constrained
420 /// template parameters.
422
423 bool hasAssociatedConstraints() const;
424
425 /// Get the underlying, templated declaration.
427
428 // Should a specialization behave like an alias for another type.
429 bool isTypeAlias() const;
430
431 // Implement isa/cast/dyncast/etc.
432 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
433
434 static bool classofKind(Kind K) {
435 return K >= firstTemplate && K <= lastTemplate;
436 }
437
438 SourceRange getSourceRange() const override LLVM_READONLY {
439 return SourceRange(getTemplateParameters()->getTemplateLoc(),
441 }
442
443protected:
446
447public:
449 TemplateParams = TParams;
450 }
451
452 /// Initialize the underlying templated declaration.
453 void init(NamedDecl *NewTemplatedDecl) {
454 if (TemplatedDecl)
455 assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl");
456 else
457 TemplatedDecl = NewTemplatedDecl;
458 }
459};
460
461/// Provides information about a function template specialization,
462/// which is a FunctionDecl that has been explicitly specialization or
463/// instantiated from a function template.
465 : public llvm::FoldingSetNode,
466 private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
467 MemberSpecializationInfo *> {
468 /// The function template specialization that this structure describes and a
469 /// flag indicating if the function is a member specialization.
470 llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
471
472 /// The function template from which this function template
473 /// specialization was generated.
474 ///
475 /// The two bits contain the top 4 values of TemplateSpecializationKind.
476 llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
477
478public:
479 /// The template arguments used to produce the function template
480 /// specialization from the function template.
482
483 /// The template arguments as written in the sources, if provided.
484 /// FIXME: Normally null; tail-allocate this.
486
487 /// The point at which this function template specialization was
488 /// first instantiated.
490
491private:
493 FunctionDecl *FD, FunctionTemplateDecl *Template,
494 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
495 const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
497 : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1),
498 TemplateArguments(TemplateArgs),
499 TemplateArgumentsAsWritten(TemplateArgsAsWritten),
501 if (MSInfo)
502 getTrailingObjects<MemberSpecializationInfo *>()[0] = MSInfo;
503 }
504
505 size_t numTrailingObjects(OverloadToken<MemberSpecializationInfo*>) const {
506 return Function.getInt();
507 }
508
509public:
511
515 const TemplateArgumentList *TemplateArgs,
516 const TemplateArgumentListInfo *TemplateArgsAsWritten,
518
519 /// Retrieve the declaration of the function template specialization.
520 FunctionDecl *getFunction() const { return Function.getPointer(); }
521
522 /// Retrieve the template from which this function was specialized.
523 FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
524
525 /// Determine what kind of template specialization this is.
527 return (TemplateSpecializationKind)(Template.getInt() + 1);
528 }
529
532 }
533
534 /// True if this declaration is an explicit specialization,
535 /// explicit instantiation declaration, or explicit instantiation
536 /// definition.
540 }
541
542 /// Set the template specialization kind.
544 assert(TSK != TSK_Undeclared &&
545 "Cannot encode TSK_Undeclared for a function template specialization");
546 Template.setInt(TSK - 1);
547 }
548
549 /// Retrieve the first point of instantiation of this function
550 /// template specialization.
551 ///
552 /// The point of instantiation may be an invalid source location if this
553 /// function has yet to be instantiated.
556 }
557
558 /// Set the (first) point of instantiation of this function template
559 /// specialization.
562 }
563
564 /// Get the specialization info if this function template specialization is
565 /// also a member specialization:
566 ///
567 /// \code
568 /// template<typename> struct A {
569 /// template<typename> void f();
570 /// template<> void f<int>();
571 /// };
572 /// \endcode
573 ///
574 /// Here, A<int>::f<int> is a function template specialization that is
575 /// an explicit specialization of A<int>::f, but it's also a member
576 /// specialization (an implicit instantiation in this case) of A::f<int>.
577 /// Further:
578 ///
579 /// \code
580 /// template<> template<> void A<int>::f<int>() {}
581 /// \endcode
582 ///
583 /// ... declares a function template specialization that is an explicit
584 /// specialization of A<int>::f, and is also an explicit member
585 /// specialization of A::f<int>.
586 ///
587 /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
588 /// need not be the same as that returned by getTemplateSpecializationKind(),
589 /// and represents the relationship between the function and the class-scope
590 /// explicit specialization in the original templated class -- whereas our
591 /// TemplateSpecializationKind represents the relationship between the
592 /// function and the function template, and should always be
593 /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
595 return numTrailingObjects(OverloadToken<MemberSpecializationInfo *>())
596 ? getTrailingObjects<MemberSpecializationInfo *>()[0]
597 : nullptr;
598 }
599
600 void Profile(llvm::FoldingSetNodeID &ID) {
601 Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
602 }
603
604 static void
605 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
606 const ASTContext &Context) {
607 ID.AddInteger(TemplateArgs.size());
608 for (const TemplateArgument &TemplateArg : TemplateArgs)
609 TemplateArg.Profile(ID, Context);
610 }
611};
612
613/// Provides information a specialization of a member of a class
614/// template, which may be a member function, static data member,
615/// member class or member enumeration.
617 // The member declaration from which this member was instantiated, and the
618 // manner in which the instantiation occurred (in the lower two bits).
619 llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
620
621 // The point at which this member was first instantiated.
622 SourceLocation PointOfInstantiation;
623
624public:
625 explicit
628 : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
629 assert(TSK != TSK_Undeclared &&
630 "Cannot encode undeclared template specializations for members");
631 }
632
633 /// Retrieve the member declaration from which this member was
634 /// instantiated.
635 NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
636
637 /// Determine what kind of template specialization this is.
639 return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
640 }
641
644 }
645
646 /// Set the template specialization kind.
648 assert(TSK != TSK_Undeclared &&
649 "Cannot encode undeclared template specializations for members");
650 MemberAndTSK.setInt(TSK - 1);
651 }
652
653 /// Retrieve the first point of instantiation of this member.
654 /// If the point of instantiation is an invalid location, then this member
655 /// has not yet been instantiated.
657 return PointOfInstantiation;
658 }
659
660 /// Set the first point of instantiation.
662 PointOfInstantiation = POI;
663 }
664};
665
666/// Provides information about a dependent function-template
667/// specialization declaration.
668///
669/// This is used for function templates explicit specializations declared
670/// within class templates:
671///
672/// \code
673/// template<typename> struct A {
674/// template<typename> void f();
675/// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo
676/// };
677/// \endcode
678///
679/// As well as dependent friend declarations naming function template
680/// specializations declared within class templates:
681///
682/// \code
683/// template <class T> void foo(T);
684/// template <class T> class A {
685/// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo
686/// };
687/// \endcode
689 : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
690 FunctionTemplateDecl *> {
691 friend TrailingObjects;
692
693 /// The number of candidates for the primary template.
694 unsigned NumCandidates;
695
697 const UnresolvedSetImpl &Candidates,
698 const ASTTemplateArgumentListInfo *TemplateArgsWritten);
699
700public:
701 /// The template arguments as written in the sources, if provided.
703
705 Create(ASTContext &Context, const UnresolvedSetImpl &Candidates,
706 const TemplateArgumentListInfo *TemplateArgs);
707
708 /// Returns the candidates for the primary function template.
710 return {getTrailingObjects<FunctionTemplateDecl *>(), NumCandidates};
711 }
712};
713
714/// Declaration of a redeclarable template.
716 public Redeclarable<RedeclarableTemplateDecl>
717{
719
720 RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
721 return getNextRedeclaration();
722 }
723
724 RedeclarableTemplateDecl *getPreviousDeclImpl() override {
725 return getPreviousDecl();
726 }
727
728 RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
729 return getMostRecentDecl();
730 }
731
732 void anchor() override;
733protected:
734 template <typename EntryType> struct SpecEntryTraits {
735 using DeclType = EntryType;
736
737 static DeclType *getDecl(EntryType *D) {
738 return D;
739 }
740
742 return D->getTemplateArgs().asArray();
743 }
744 };
745
746 template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
747 typename DeclType = typename SETraits::DeclType>
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() const;
774
775 template <class EntryType, typename ...ProfileArguments>
777 findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
778 void *&InsertPos, ProfileArguments &&...ProfileArgs);
779
780 template <class Derived, class EntryType>
781 void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
782 EntryType *Entry, void *InsertPos);
783
784 struct CommonBase {
786
787 /// The template from which this was most
788 /// directly instantiated (or null).
789 ///
790 /// The boolean value indicates whether this template
791 /// was explicitly specialized.
792 llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
794
795 /// If non-null, points to an array of specializations (including
796 /// partial specializations) known only by their external declaration IDs.
797 ///
798 /// The first value in the array is the number of specializations/partial
799 /// specializations that follow.
801
802 /// The set of "injected" template arguments used within this
803 /// template.
804 ///
805 /// This pointer refers to the template arguments (there are as
806 /// many template arguments as template parameters) for the
807 /// template, and is allocated lazily, since most templates do not
808 /// require the use of this information.
810 };
811
812 /// Pointer to the common data shared by all declarations of this
813 /// template.
814 mutable CommonBase *Common = nullptr;
815
816 /// Retrieves the "common" pointer shared by all (re-)declarations of
817 /// the same template. Calling this routine may implicitly allocate memory
818 /// for the common pointer.
819 CommonBase *getCommonPtr() const;
820
821 virtual CommonBase *newCommon(ASTContext &C) const = 0;
822
823 // Construct a template decl with name, parameters, and templated element.
827 : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
828
829public:
830 friend class ASTDeclReader;
831 friend class ASTDeclWriter;
832 friend class ASTReader;
833 template <class decl_type> friend class RedeclarableTemplate;
834
835 /// Retrieves the canonical declaration of this template.
837 return getFirstDecl();
838 }
840 return getFirstDecl();
841 }
842
843 /// Determines whether this template was a specialization of a
844 /// member template.
845 ///
846 /// In the following example, the function template \c X<int>::f and the
847 /// member template \c X<int>::Inner are member specializations.
848 ///
849 /// \code
850 /// template<typename T>
851 /// struct X {
852 /// template<typename U> void f(T, U);
853 /// template<typename U> struct Inner;
854 /// };
855 ///
856 /// template<> template<typename T>
857 /// void X<int>::f(int, T);
858 /// template<> template<typename T>
859 /// struct X<int>::Inner { /* ... */ };
860 /// \endcode
862 return getCommonPtr()->InstantiatedFromMember.getInt();
863 }
864
865 /// Note that this member template is a specialization.
867 assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
868 "Only member templates can be member template specializations");
869 getCommonPtr()->InstantiatedFromMember.setInt(true);
870 }
871
872 /// Retrieve the member template from which this template was
873 /// instantiated, or nullptr if this template was not instantiated from a
874 /// member template.
875 ///
876 /// A template is instantiated from a member template when the member
877 /// template itself is part of a class template (or member thereof). For
878 /// example, given
879 ///
880 /// \code
881 /// template<typename T>
882 /// struct X {
883 /// template<typename U> void f(T, U);
884 /// };
885 ///
886 /// void test(X<int> x) {
887 /// x.f(1, 'a');
888 /// };
889 /// \endcode
890 ///
891 /// \c X<int>::f is a FunctionTemplateDecl that describes the function
892 /// template
893 ///
894 /// \code
895 /// template<typename U> void X<int>::f(int, U);
896 /// \endcode
897 ///
898 /// which was itself created during the instantiation of \c X<int>. Calling
899 /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
900 /// retrieve the FunctionTemplateDecl for the original template \c f within
901 /// the class template \c X<T>, i.e.,
902 ///
903 /// \code
904 /// template<typename T>
905 /// template<typename U>
906 /// void X<T>::f(T, U);
907 /// \endcode
909 return getCommonPtr()->InstantiatedFromMember.getPointer();
910 }
911
913 assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
914 getCommonPtr()->InstantiatedFromMember.setPointer(TD);
915 }
916
917 /// Retrieve the "injected" template arguments that correspond to the
918 /// template parameters of this template.
919 ///
920 /// Although the C++ standard has no notion of the "injected" template
921 /// arguments for a template, the notion is convenient when
922 /// we need to perform substitutions inside the definition of a template.
924
926 using redecl_iterator = redeclarable_base::redecl_iterator;
927
934
935 // Implement isa/cast/dyncast/etc.
936 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
937
938 static bool classofKind(Kind K) {
939 return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
940 }
941};
942
943template <> struct RedeclarableTemplateDecl::
944SpecEntryTraits<FunctionTemplateSpecializationInfo> {
946
948 return I->getFunction();
949 }
950
953 return I->TemplateArguments->asArray();
954 }
955};
956
957/// Declaration of a template function.
959protected:
960 friend class FunctionDecl;
961
962 /// Data that is common to all of the declarations of a given
963 /// function template.
965 /// The function template specializations for this function
966 /// template, including explicit specializations and instantiations.
967 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
968
969 Common() = default;
970 };
971
975 : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
976 Decl) {}
977
978 CommonBase *newCommon(ASTContext &C) const override;
979
981 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
982 }
983
984 /// Retrieve the set of function template specializations of this
985 /// function template.
986 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
987 getSpecializations() const;
988
989 /// Add a specialization of this function template.
990 ///
991 /// \param InsertPos Insert position in the FoldingSetVector, must have been
992 /// retrieved by an earlier call to findSpecialization().
994 void *InsertPos);
995
996public:
997 friend class ASTDeclReader;
998 friend class ASTDeclWriter;
999
1000 /// Load any lazily-loaded specializations from the external source.
1001 void LoadLazySpecializations() const;
1002
1003 /// Get the underlying function declaration of the template.
1005 return static_cast<FunctionDecl *>(TemplatedDecl);
1006 }
1007
1008 /// Returns whether this template declaration defines the primary
1009 /// pattern.
1012 }
1013
1014 /// Return the specialization with the provided arguments if it exists,
1015 /// otherwise return the insertion point.
1017 void *&InsertPos);
1018
1020 return cast<FunctionTemplateDecl>(
1022 }
1024 return cast<FunctionTemplateDecl>(
1026 }
1027
1028 /// Retrieve the previous declaration of this function template, or
1029 /// nullptr if no such declaration exists.
1031 return cast_or_null<FunctionTemplateDecl>(
1032 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1033 }
1035 return cast_or_null<FunctionTemplateDecl>(
1036 static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
1037 }
1038
1040 return cast<FunctionTemplateDecl>(
1041 static_cast<RedeclarableTemplateDecl *>(this)
1042 ->getMostRecentDecl());
1043 }
1045 return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
1046 }
1047
1049 return cast_or_null<FunctionTemplateDecl>(
1051 }
1052
1054 using spec_range = llvm::iterator_range<spec_iterator>;
1055
1057 return spec_range(spec_begin(), spec_end());
1058 }
1059
1061 return makeSpecIterator(getSpecializations(), false);
1062 }
1063
1065 return makeSpecIterator(getSpecializations(), true);
1066 }
1067
1068 /// Return whether this function template is an abbreviated function template,
1069 /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
1070 bool isAbbreviated() const {
1071 // Since the invented template parameters generated from 'auto' parameters
1072 // are either appended to the end of the explicit template parameter list or
1073 // form a new template parameter list, we can simply observe the last
1074 // parameter to determine if such a thing happened.
1076 return TPL->getParam(TPL->size() - 1)->isImplicit();
1077 }
1078
1079 /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
1081
1082 /// Create a function template node.
1085 DeclarationName Name,
1086 TemplateParameterList *Params,
1087 NamedDecl *Decl);
1088
1089 /// Create an empty function template node.
1092
1093 // Implement isa/cast/dyncast support
1094 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1095 static bool classofKind(Kind K) { return K == FunctionTemplate; }
1096};
1097
1098//===----------------------------------------------------------------------===//
1099// Kinds of Template Parameters
1100//===----------------------------------------------------------------------===//
1101
1102/// Defines the position of a template parameter within a template
1103/// parameter list.
1104///
1105/// Because template parameter can be listed
1106/// sequentially for out-of-line template members, each template parameter is
1107/// given a Depth - the nesting of template parameter scopes - and a Position -
1108/// the occurrence within the parameter list.
1109/// This class is inheritedly privately by different kinds of template
1110/// parameters and is not part of the Decl hierarchy. Just a facility.
1112protected:
1113 enum { DepthWidth = 20, PositionWidth = 12 };
1114 unsigned Depth : DepthWidth;
1116
1117 static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1;
1118 static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1;
1119
1120 TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {
1121 // The input may fill maximum values to show that it is invalid.
1122 // Add one here to convert it to zero.
1123 assert((D + 1) <= MaxDepth &&
1124 "The depth of template parmeter position is more than 2^20!");
1125 assert((P + 1) <= MaxPosition &&
1126 "The position of template parmeter position is more than 2^12!");
1127 }
1128
1129public:
1131
1132 /// Get the nesting depth of the template parameter.
1133 unsigned getDepth() const { return Depth; }
1134 void setDepth(unsigned D) {
1135 assert((D + 1) <= MaxDepth &&
1136 "The depth of template parmeter position is more than 2^20!");
1137 Depth = D;
1138 }
1139
1140 /// Get the position of the template parameter within its parameter list.
1141 unsigned getPosition() const { return Position; }
1142 void setPosition(unsigned P) {
1143 assert((P + 1) <= MaxPosition &&
1144 "The position of template parmeter position is more than 2^12!");
1145 Position = P;
1146 }
1147
1148 /// Get the index of the template parameter within its parameter list.
1149 unsigned getIndex() const { return Position; }
1150};
1151
1152/// Declaration of a template type parameter.
1153///
1154/// For example, "T" in
1155/// \code
1156/// template<typename T> class vector;
1157/// \endcode
1158class TemplateTypeParmDecl final : public TypeDecl,
1159 private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> {
1160 /// Sema creates these on the stack during auto type deduction.
1161 friend class Sema;
1162 friend TrailingObjects;
1163 friend class ASTDeclReader;
1164
1165 /// Whether this template type parameter was declaration with
1166 /// the 'typename' keyword.
1167 ///
1168 /// If false, it was declared with the 'class' keyword.
1169 bool Typename : 1;
1170
1171 /// Whether this template type parameter has a type-constraint construct.
1172 bool HasTypeConstraint : 1;
1173
1174 /// Whether the type constraint has been initialized. This can be false if the
1175 /// constraint was not initialized yet or if there was an error forming the
1176 /// type constraint.
1177 bool TypeConstraintInitialized : 1;
1178
1179 /// Whether this type template parameter is an "expanded"
1180 /// parameter pack, meaning that its type is a pack expansion and we
1181 /// already know the set of types that expansion expands to.
1182 bool ExpandedParameterPack : 1;
1183
1184 /// The number of type parameters in an expanded parameter pack.
1185 unsigned NumExpanded = 0;
1186
1187 /// The default template argument, if any.
1188 using DefArgStorage =
1190 DefArgStorage DefaultArgument;
1191
1193 SourceLocation IdLoc, IdentifierInfo *Id, bool Typename,
1194 bool HasTypeConstraint,
1195 std::optional<unsigned> NumExpanded)
1196 : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
1197 HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false),
1198 ExpandedParameterPack(NumExpanded),
1199 NumExpanded(NumExpanded.value_or(0)) {}
1200
1201public:
1202 static TemplateTypeParmDecl *
1203 Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
1204 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
1205 bool Typename, bool ParameterPack, bool HasTypeConstraint = false,
1206 std::optional<unsigned> NumExpanded = std::nullopt);
1211 bool HasTypeConstraint);
1212
1213 /// Whether this template type parameter was declared with
1214 /// the 'typename' keyword.
1215 ///
1216 /// If not, it was either declared with the 'class' keyword or with a
1217 /// type-constraint (see hasTypeConstraint()).
1219 return Typename && !HasTypeConstraint;
1220 }
1221
1222 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1223
1224 /// Determine whether this template parameter has a default
1225 /// argument.
1226 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1227
1228 /// Retrieve the default argument, if any.
1230 return DefaultArgument.get()->getType();
1231 }
1232
1233 /// Retrieves the default argument's source information, if any.
1235 return DefaultArgument.get();
1236 }
1237
1238 /// Retrieves the location of the default argument declaration.
1240
1241 /// Determines whether the default argument was inherited
1242 /// from a previous declaration of this template.
1244 return DefaultArgument.isInherited();
1245 }
1246
1247 /// Set the default argument for this template parameter.
1249 DefaultArgument.set(DefArg);
1250 }
1251
1252 /// Set that this default argument was inherited from another
1253 /// parameter.
1255 TemplateTypeParmDecl *Prev) {
1256 DefaultArgument.setInherited(C, Prev);
1257 }
1258
1259 /// Removes the default argument of this template parameter.
1261 DefaultArgument.clear();
1262 }
1263
1264 /// Set whether this template type parameter was declared with
1265 /// the 'typename' or 'class' keyword.
1266 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1267
1268 /// Retrieve the depth of the template parameter.
1269 unsigned getDepth() const;
1270
1271 /// Retrieve the index of the template parameter.
1272 unsigned getIndex() const;
1273
1274 /// Returns whether this is a parameter pack.
1275 bool isParameterPack() const;
1276
1277 /// Whether this parameter pack is a pack expansion.
1278 ///
1279 /// A template type template parameter pack can be a pack expansion if its
1280 /// type-constraint contains an unexpanded parameter pack.
1281 bool isPackExpansion() const {
1282 if (!isParameterPack())
1283 return false;
1284 if (const TypeConstraint *TC = getTypeConstraint())
1285 if (TC->hasExplicitTemplateArgs())
1286 for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
1287 if (ArgLoc.getArgument().containsUnexpandedParameterPack())
1288 return true;
1289 return false;
1290 }
1291
1292 /// Whether this parameter is a template type parameter pack that has a known
1293 /// list of different type-constraints at different positions.
1294 ///
1295 /// A parameter pack is an expanded parameter pack when the original
1296 /// parameter pack's type-constraint was itself a pack expansion, and that
1297 /// expansion has already been expanded. For example, given:
1298 ///
1299 /// \code
1300 /// template<typename ...Types>
1301 /// struct X {
1302 /// template<convertible_to<Types> ...Convertibles>
1303 /// struct Y { /* ... */ };
1304 /// };
1305 /// \endcode
1306 ///
1307 /// The parameter pack \c Convertibles has (convertible_to<Types> && ...) as
1308 /// its type-constraint. When \c Types is supplied with template arguments by
1309 /// instantiating \c X, the instantiation of \c Convertibles becomes an
1310 /// expanded parameter pack. For example, instantiating
1311 /// \c X<int, unsigned int> results in \c Convertibles being an expanded
1312 /// parameter pack of size 2 (use getNumExpansionTypes() to get this number).
1313 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1314
1315 /// Retrieves the number of parameters in an expanded parameter pack.
1316 unsigned getNumExpansionParameters() const {
1317 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1318 return NumExpanded;
1319 }
1320
1321 /// Returns the type constraint associated with this template parameter (if
1322 /// any).
1324 return TypeConstraintInitialized ? getTrailingObjects<TypeConstraint>() :
1325 nullptr;
1326 }
1327
1329 Expr *ImmediatelyDeclaredConstraint);
1330
1331 /// Determine whether this template parameter has a type-constraint.
1332 bool hasTypeConstraint() const {
1333 return HasTypeConstraint;
1334 }
1335
1336 /// \brief Get the associated-constraints of this template parameter.
1337 /// This will either be the immediately-introduced constraint or empty.
1338 ///
1339 /// Use this instead of getTypeConstraint for concepts APIs that
1340 /// accept an ArrayRef of constraint expressions.
1342 if (HasTypeConstraint)
1343 AC.push_back(getTypeConstraint()->getImmediatelyDeclaredConstraint());
1344 }
1345
1346 SourceRange getSourceRange() const override LLVM_READONLY;
1347
1348 // Implement isa/cast/dyncast/etc.
1349 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1350 static bool classofKind(Kind K) { return K == TemplateTypeParm; }
1351};
1352
1353/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
1354/// e.g., "Size" in
1355/// @code
1356/// template<int Size> class array { };
1357/// @endcode
1359 : public DeclaratorDecl,
1360 protected TemplateParmPosition,
1361 private llvm::TrailingObjects<NonTypeTemplateParmDecl,
1362 std::pair<QualType, TypeSourceInfo *>,
1363 Expr *> {
1364 friend class ASTDeclReader;
1365 friend TrailingObjects;
1366
1367 /// The default template argument, if any, and whether or not
1368 /// it was inherited.
1370 DefArgStorage DefaultArgument;
1371
1372 // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
1373 // down here to save memory.
1374
1375 /// Whether this non-type template parameter is a parameter pack.
1376 bool ParameterPack;
1377
1378 /// Whether this non-type template parameter is an "expanded"
1379 /// parameter pack, meaning that its type is a pack expansion and we
1380 /// already know the set of types that expansion expands to.
1381 bool ExpandedParameterPack = false;
1382
1383 /// The number of types in an expanded parameter pack.
1384 unsigned NumExpandedTypes = 0;
1385
1386 size_t numTrailingObjects(
1387 OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
1388 return NumExpandedTypes;
1389 }
1390
1392 SourceLocation IdLoc, unsigned D, unsigned P,
1393 const IdentifierInfo *Id, QualType T,
1394 bool ParameterPack, TypeSourceInfo *TInfo)
1395 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
1396 TemplateParmPosition(D, P), ParameterPack(ParameterPack) {}
1397
1398 NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
1399 SourceLocation IdLoc, unsigned D, unsigned P,
1400 const IdentifierInfo *Id, QualType T,
1401 TypeSourceInfo *TInfo,
1402 ArrayRef<QualType> ExpandedTypes,
1403 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1404
1405public:
1406 static NonTypeTemplateParmDecl *
1407 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1408 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
1409 QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
1410
1411 static NonTypeTemplateParmDecl *
1412 Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
1413 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
1414 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
1415 ArrayRef<TypeSourceInfo *> ExpandedTInfos);
1416
1417 static NonTypeTemplateParmDecl *
1418 CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint);
1419 static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
1420 GlobalDeclID ID,
1421 unsigned NumExpandedTypes,
1422 bool HasTypeConstraint);
1423
1429
1430 SourceRange getSourceRange() const override LLVM_READONLY;
1431
1432 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1433
1434 /// Determine whether this template parameter has a default
1435 /// argument.
1436 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1437
1438 /// Retrieve the default argument, if any.
1439 Expr *getDefaultArgument() const { return DefaultArgument.get(); }
1440
1441 /// Retrieve the location of the default argument, if any.
1443
1444 /// Determines whether the default argument was inherited
1445 /// from a previous declaration of this template.
1447 return DefaultArgument.isInherited();
1448 }
1449
1450 /// Set the default argument for this template parameter, and
1451 /// whether that default argument was inherited from another
1452 /// declaration.
1453 void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
1456 DefaultArgument.setInherited(C, Parm);
1457 }
1458
1459 /// Removes the default argument of this template parameter.
1460 void removeDefaultArgument() { DefaultArgument.clear(); }
1461
1462 /// Whether this parameter is a non-type template parameter pack.
1463 ///
1464 /// If the parameter is a parameter pack, the type may be a
1465 /// \c PackExpansionType. In the following example, the \c Dims parameter
1466 /// is a parameter pack (whose type is 'unsigned').
1467 ///
1468 /// \code
1469 /// template<typename T, unsigned ...Dims> struct multi_array;
1470 /// \endcode
1471 bool isParameterPack() const { return ParameterPack; }
1472
1473 /// Whether this parameter pack is a pack expansion.
1474 ///
1475 /// A non-type template parameter pack is a pack expansion if its type
1476 /// contains an unexpanded parameter pack. In this case, we will have
1477 /// built a PackExpansionType wrapping the type.
1478 bool isPackExpansion() const {
1479 return ParameterPack && getType()->getAs<PackExpansionType>();
1480 }
1481
1482 /// Whether this parameter is a non-type template parameter pack
1483 /// that has a known list of different types at different positions.
1484 ///
1485 /// A parameter pack is an expanded parameter pack when the original
1486 /// parameter pack's type was itself a pack expansion, and that expansion
1487 /// has already been expanded. For example, given:
1488 ///
1489 /// \code
1490 /// template<typename ...Types>
1491 /// struct X {
1492 /// template<Types ...Values>
1493 /// struct Y { /* ... */ };
1494 /// };
1495 /// \endcode
1496 ///
1497 /// The parameter pack \c Values has a \c PackExpansionType as its type,
1498 /// which expands \c Types. When \c Types is supplied with template arguments
1499 /// by instantiating \c X, the instantiation of \c Values becomes an
1500 /// expanded parameter pack. For example, instantiating
1501 /// \c X<int, unsigned int> results in \c Values being an expanded parameter
1502 /// pack with expansion types \c int and \c unsigned int.
1503 ///
1504 /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
1505 /// return the expansion types.
1506 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1507
1508 /// Retrieves the number of expansion types in an expanded parameter
1509 /// pack.
1510 unsigned getNumExpansionTypes() const {
1511 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1512 return NumExpandedTypes;
1513 }
1514
1515 /// Retrieve a particular expansion type within an expanded parameter
1516 /// pack.
1517 QualType getExpansionType(unsigned I) const {
1518 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1519 auto TypesAndInfos =
1520 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1521 return TypesAndInfos[I].first;
1522 }
1523
1524 /// Retrieve a particular expansion type source info within an
1525 /// expanded parameter pack.
1527 assert(I < NumExpandedTypes && "Out-of-range expansion type index");
1528 auto TypesAndInfos =
1529 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
1530 return TypesAndInfos[I].second;
1531 }
1532
1533 /// Return the constraint introduced by the placeholder type of this non-type
1534 /// template parameter (if any).
1536 return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
1537 nullptr;
1538 }
1539
1541 *getTrailingObjects<Expr *>() = E;
1542 }
1543
1544 /// Determine whether this non-type template parameter's type has a
1545 /// placeholder with a type-constraint.
1547 auto *AT = getType()->getContainedAutoType();
1548 return AT && AT->isConstrained();
1549 }
1550
1551 /// \brief Get the associated-constraints of this template parameter.
1552 /// This will either be a vector of size 1 containing the immediately-declared
1553 /// constraint introduced by the placeholder type, or an empty vector.
1554 ///
1555 /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
1556 /// concepts APIs that accept an ArrayRef of constraint expressions.
1559 AC.push_back(E);
1560 }
1561
1562 // Implement isa/cast/dyncast/etc.
1563 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1564 static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
1565};
1566
1567/// TemplateTemplateParmDecl - Declares a template template parameter,
1568/// e.g., "T" in
1569/// @code
1570/// template <template <typename> class T> class container { };
1571/// @endcode
1572/// A template template parameter is a TemplateDecl because it defines the
1573/// name of a template and the template parameters allowable for substitution.
1575 : public TemplateDecl,
1576 protected TemplateParmPosition,
1577 private llvm::TrailingObjects<TemplateTemplateParmDecl,
1578 TemplateParameterList *> {
1579 /// The default template argument, if any.
1580 using DefArgStorage =
1582 DefArgStorage DefaultArgument;
1583
1584 /// Whether this template template parameter was declaration with
1585 /// the 'typename' keyword.
1586 ///
1587 /// If false, it was declared with the 'class' keyword.
1588 LLVM_PREFERRED_TYPE(bool)
1589 unsigned Typename : 1;
1590
1591 /// Whether this parameter is a parameter pack.
1592 LLVM_PREFERRED_TYPE(bool)
1593 unsigned ParameterPack : 1;
1594
1595 /// Whether this template template parameter is an "expanded"
1596 /// parameter pack, meaning that it is a pack expansion and we
1597 /// already know the set of template parameters that expansion expands to.
1598 LLVM_PREFERRED_TYPE(bool)
1599 unsigned ExpandedParameterPack : 1;
1600
1601 /// The number of parameters in an expanded parameter pack.
1602 unsigned NumExpandedParams = 0;
1603
1605 unsigned P, bool ParameterPack, IdentifierInfo *Id,
1606 bool Typename, TemplateParameterList *Params)
1607 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
1609 ParameterPack(ParameterPack), ExpandedParameterPack(false) {}
1610
1612 unsigned P, IdentifierInfo *Id, bool Typename,
1613 TemplateParameterList *Params,
1615
1616 void anchor() override;
1617
1618public:
1619 friend class ASTDeclReader;
1620 friend class ASTDeclWriter;
1622
1624 SourceLocation L, unsigned D,
1625 unsigned P, bool ParameterPack,
1626 IdentifierInfo *Id, bool Typename,
1627 TemplateParameterList *Params);
1629 Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
1630 unsigned P, IdentifierInfo *Id, bool Typename,
1631 TemplateParameterList *Params,
1633
1637 CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions);
1638
1644
1645 /// Whether this template template parameter was declared with
1646 /// the 'typename' keyword.
1647 bool wasDeclaredWithTypename() const { return Typename; }
1648
1649 /// Set whether this template template parameter was declared with
1650 /// the 'typename' or 'class' keyword.
1651 void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
1652
1653 /// Whether this template template parameter is a template
1654 /// parameter pack.
1655 ///
1656 /// \code
1657 /// template<template <class T> ...MetaFunctions> struct Apply;
1658 /// \endcode
1659 bool isParameterPack() const { return ParameterPack; }
1660
1661 /// Whether this parameter pack is a pack expansion.
1662 ///
1663 /// A template template parameter pack is a pack expansion if its template
1664 /// parameter list contains an unexpanded parameter pack.
1665 bool isPackExpansion() const {
1666 return ParameterPack &&
1668 }
1669
1670 /// Whether this parameter is a template template parameter pack that
1671 /// has a known list of different template parameter lists at different
1672 /// positions.
1673 ///
1674 /// A parameter pack is an expanded parameter pack when the original parameter
1675 /// pack's template parameter list was itself a pack expansion, and that
1676 /// expansion has already been expanded. For exampe, given:
1677 ///
1678 /// \code
1679 /// template<typename...Types> struct Outer {
1680 /// template<template<Types> class...Templates> struct Inner;
1681 /// };
1682 /// \endcode
1683 ///
1684 /// The parameter pack \c Templates is a pack expansion, which expands the
1685 /// pack \c Types. When \c Types is supplied with template arguments by
1686 /// instantiating \c Outer, the instantiation of \c Templates is an expanded
1687 /// parameter pack.
1688 bool isExpandedParameterPack() const { return ExpandedParameterPack; }
1689
1690 /// Retrieves the number of expansion template parameters in
1691 /// an expanded parameter pack.
1693 assert(ExpandedParameterPack && "Not an expansion parameter pack");
1694 return NumExpandedParams;
1695 }
1696
1697 /// Retrieve a particular expansion type within an expanded parameter
1698 /// pack.
1700 assert(I < NumExpandedParams && "Out-of-range expansion type index");
1701 return getTrailingObjects<TemplateParameterList *>()[I];
1702 }
1703
1704 const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
1705
1706 /// Determine whether this template parameter has a default
1707 /// argument.
1708 bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
1709
1710 /// Retrieve the default argument, if any.
1712 static const TemplateArgumentLoc NoneLoc;
1713 return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc;
1714 }
1715
1716 /// Retrieve the location of the default argument, if any.
1718
1719 /// Determines whether the default argument was inherited
1720 /// from a previous declaration of this template.
1722 return DefaultArgument.isInherited();
1723 }
1724
1725 /// Set the default argument for this template parameter, and
1726 /// whether that default argument was inherited from another
1727 /// declaration.
1728 void setDefaultArgument(const ASTContext &C,
1729 const TemplateArgumentLoc &DefArg);
1732 DefaultArgument.setInherited(C, Prev);
1733 }
1734
1735 /// Removes the default argument of this template parameter.
1736 void removeDefaultArgument() { DefaultArgument.clear(); }
1737
1738 SourceRange getSourceRange() const override LLVM_READONLY {
1742 return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
1743 }
1744
1745 // Implement isa/cast/dyncast/etc.
1746 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1747 static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
1748};
1749
1750/// Represents the builtin template declaration which is used to
1751/// implement __make_integer_seq and other builtin templates. It serves
1752/// no real purpose beyond existing as a place to hold template parameters.
1755
1758
1759 void anchor() override;
1760
1761public:
1762 // Implement isa/cast/dyncast support
1763 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1764 static bool classofKind(Kind K) { return K == BuiltinTemplate; }
1765
1767 DeclarationName Name,
1768 BuiltinTemplateKind BTK) {
1769 return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
1770 }
1771
1772 SourceRange getSourceRange() const override LLVM_READONLY {
1773 return {};
1774 }
1775
1777};
1778
1779/// Represents a class template specialization, which refers to
1780/// a class template with a given set of template arguments.
1781///
1782/// Class template specializations represent both explicit
1783/// specialization of class templates, as in the example below, and
1784/// implicit instantiations of class templates.
1785///
1786/// \code
1787/// template<typename T> class array;
1788///
1789/// template<>
1790/// class array<bool> { }; // class template specialization array<bool>
1791/// \endcode
1793 : public CXXRecordDecl, public llvm::FoldingSetNode {
1794 /// Structure that stores information about a class template
1795 /// specialization that was instantiated from a class template partial
1796 /// specialization.
1797 struct SpecializedPartialSpecialization {
1798 /// The class template partial specialization from which this
1799 /// class template specialization was instantiated.
1800 ClassTemplatePartialSpecializationDecl *PartialSpecialization;
1801
1802 /// The template argument list deduced for the class template
1803 /// partial specialization itself.
1804 const TemplateArgumentList *TemplateArgs;
1805 };
1806
1807 /// The template that this specialization specializes
1808 llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
1809 SpecializedTemplate;
1810
1811 /// Further info for explicit template specialization/instantiation.
1812 struct ExplicitSpecializationInfo {
1813 /// The type-as-written.
1814 TypeSourceInfo *TypeAsWritten = nullptr;
1815
1816 /// The location of the extern keyword.
1817 SourceLocation ExternLoc;
1818
1819 /// The location of the template keyword.
1820 SourceLocation TemplateKeywordLoc;
1821
1822 ExplicitSpecializationInfo() = default;
1823 };
1824
1825 /// Further info for explicit template specialization/instantiation.
1826 /// Does not apply to implicit specializations.
1827 ExplicitSpecializationInfo *ExplicitInfo = nullptr;
1828
1829 /// The template arguments used to describe this specialization.
1830 const TemplateArgumentList *TemplateArgs;
1831
1832 /// The point where this template was instantiated (if any)
1833 SourceLocation PointOfInstantiation;
1834
1835 /// The kind of specialization this declaration refers to.
1836 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
1837 unsigned SpecializationKind : 3;
1838
1839protected:
1841 DeclContext *DC, SourceLocation StartLoc,
1842 SourceLocation IdLoc,
1843 ClassTemplateDecl *SpecializedTemplate,
1846
1848
1849public:
1850 friend class ASTDeclReader;
1851 friend class ASTDeclWriter;
1852
1854 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
1855 SourceLocation StartLoc, SourceLocation IdLoc,
1856 ClassTemplateDecl *SpecializedTemplate,
1861
1862 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
1863 bool Qualified) const override;
1864
1865 // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
1866 // different "most recent" declaration from this function for the same
1867 // declaration, because we don't override getMostRecentDeclImpl(). But
1868 // it's not clear that we should override that, because the most recent
1869 // declaration as a CXXRecordDecl sometimes is the injected-class-name.
1871 return cast<ClassTemplateSpecializationDecl>(
1873 }
1874
1875 /// Retrieve the template that this specialization specializes.
1877
1878 /// Retrieve the template arguments of the class template
1879 /// specialization.
1881 return *TemplateArgs;
1882 }
1883
1885 TemplateArgs = Args;
1886 }
1887
1888 /// Determine the kind of specialization that this
1889 /// declaration represents.
1891 return static_cast<TemplateSpecializationKind>(SpecializationKind);
1892 }
1893
1896 }
1897
1898 /// Is this an explicit specialization at class scope (within the class that
1899 /// owns the primary template)? For example:
1900 ///
1901 /// \code
1902 /// template<typename T> struct Outer {
1903 /// template<typename U> struct Inner;
1904 /// template<> struct Inner; // class-scope explicit specialization
1905 /// };
1906 /// \endcode
1908 return isExplicitSpecialization() &&
1909 isa<CXXRecordDecl>(getLexicalDeclContext());
1910 }
1911
1912 /// True if this declaration is an explicit specialization,
1913 /// explicit instantiation declaration, or explicit instantiation
1914 /// definition.
1918 }
1919
1921 SpecializedTemplate = Specialized;
1922 }
1923
1925 SpecializationKind = TSK;
1926 }
1927
1928 /// Get the point of instantiation (if any), or null if none.
1930 return PointOfInstantiation;
1931 }
1932
1934 assert(Loc.isValid() && "point of instantiation must be valid!");
1935 PointOfInstantiation = Loc;
1936 }
1937
1938 /// If this class template specialization is an instantiation of
1939 /// a template (rather than an explicit specialization), return the
1940 /// class template or class template partial specialization from which it
1941 /// was instantiated.
1942 llvm::PointerUnion<ClassTemplateDecl *,
1946 return llvm::PointerUnion<ClassTemplateDecl *,
1948
1950 }
1951
1952 /// Retrieve the class template or class template partial
1953 /// specialization which was specialized by this.
1954 llvm::PointerUnion<ClassTemplateDecl *,
1957 if (const auto *PartialSpec =
1958 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1959 return PartialSpec->PartialSpecialization;
1960
1961 return SpecializedTemplate.get<ClassTemplateDecl*>();
1962 }
1963
1964 /// Retrieve the set of template arguments that should be used
1965 /// to instantiate members of the class template or class template partial
1966 /// specialization from which this class template specialization was
1967 /// instantiated.
1968 ///
1969 /// \returns For a class template specialization instantiated from the primary
1970 /// template, this function will return the same template arguments as
1971 /// getTemplateArgs(). For a class template specialization instantiated from
1972 /// a class template partial specialization, this function will return the
1973 /// deduced template arguments for the class template partial specialization
1974 /// itself.
1976 if (const auto *PartialSpec =
1977 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1978 return *PartialSpec->TemplateArgs;
1979
1980 return getTemplateArgs();
1981 }
1982
1983 /// Note that this class template specialization is actually an
1984 /// instantiation of the given class template partial specialization whose
1985 /// template arguments have been deduced.
1987 const TemplateArgumentList *TemplateArgs) {
1988 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
1989 "Already set to a class template partial specialization!");
1990 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
1991 PS->PartialSpecialization = PartialSpec;
1992 PS->TemplateArgs = TemplateArgs;
1993 SpecializedTemplate = PS;
1994 }
1995
1996 /// Note that this class template specialization is an instantiation
1997 /// of the given class template.
1999 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
2000 "Previously set to a class template partial specialization!");
2001 SpecializedTemplate = TemplDecl;
2002 }
2003
2004 /// Sets the type of this specialization as it was written by
2005 /// the user. This will be a class template specialization type.
2007 if (!ExplicitInfo)
2008 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2009 ExplicitInfo->TypeAsWritten = T;
2010 }
2011
2012 /// Gets the type of this specialization as it was written by
2013 /// the user, if it was so written.
2015 return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
2016 }
2017
2018 /// Gets the location of the extern keyword, if present.
2020 return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2021 }
2022
2023 /// Sets the location of the extern keyword.
2025 if (!ExplicitInfo)
2026 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2027 ExplicitInfo->ExternLoc = Loc;
2028 }
2029
2030 /// Sets the location of the template keyword.
2032 if (!ExplicitInfo)
2033 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2034 ExplicitInfo->TemplateKeywordLoc = Loc;
2035 }
2036
2037 /// Gets the location of the template keyword, if present.
2039 return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2040 }
2041
2042 SourceRange getSourceRange() const override LLVM_READONLY;
2043
2044 void Profile(llvm::FoldingSetNodeID &ID) const {
2045 Profile(ID, TemplateArgs->asArray(), getASTContext());
2046 }
2047
2048 static void
2049 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2050 const ASTContext &Context) {
2051 ID.AddInteger(TemplateArgs.size());
2052 for (const TemplateArgument &TemplateArg : TemplateArgs)
2053 TemplateArg.Profile(ID, Context);
2054 }
2055
2056 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2057
2058 static bool classofKind(Kind K) {
2059 return K >= firstClassTemplateSpecialization &&
2060 K <= lastClassTemplateSpecialization;
2061 }
2062};
2063
2066 /// The list of template parameters
2067 TemplateParameterList* TemplateParams = nullptr;
2068
2069 /// The source info for the template arguments as written.
2070 /// FIXME: redundant with TypeAsWritten?
2071 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
2072
2073 /// The class template partial specialization from which this
2074 /// class template partial specialization was instantiated.
2075 ///
2076 /// The boolean value will be true to indicate that this class template
2077 /// partial specialization was specialized at this level.
2078 llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
2079 InstantiatedFromMember;
2080
2082 DeclContext *DC,
2083 SourceLocation StartLoc,
2084 SourceLocation IdLoc,
2085 TemplateParameterList *Params,
2086 ClassTemplateDecl *SpecializedTemplate,
2088 const ASTTemplateArgumentListInfo *ArgsAsWritten,
2090
2092 : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
2093 InstantiatedFromMember(nullptr, false) {}
2094
2095 void anchor() override;
2096
2097public:
2098 friend class ASTDeclReader;
2099 friend class ASTDeclWriter;
2100
2102 Create(ASTContext &Context, TagKind TK, DeclContext *DC,
2103 SourceLocation StartLoc, SourceLocation IdLoc,
2104 TemplateParameterList *Params,
2105 ClassTemplateDecl *SpecializedTemplate,
2107 const TemplateArgumentListInfo &ArgInfos,
2108 QualType CanonInjectedType,
2110
2113
2115 return cast<ClassTemplatePartialSpecializationDecl>(
2116 static_cast<ClassTemplateSpecializationDecl *>(
2117 this)->getMostRecentDecl());
2118 }
2119
2120 /// Get the list of template parameters
2122 return TemplateParams;
2123 }
2124
2125 /// \brief All associated constraints of this partial specialization,
2126 /// including the requires clause and any constraints derived from
2127 /// constrained-parameters.
2128 ///
2129 /// The constraints in the resulting list are to be treated as if in a
2130 /// conjunction ("and").
2132 TemplateParams->getAssociatedConstraints(AC);
2133 }
2134
2136 return TemplateParams->hasAssociatedConstraints();
2137 }
2138
2139 /// Get the template arguments as written.
2141 return ArgsAsWritten;
2142 }
2143
2144 /// Retrieve the member class template partial specialization from
2145 /// which this particular class template partial specialization was
2146 /// instantiated.
2147 ///
2148 /// \code
2149 /// template<typename T>
2150 /// struct Outer {
2151 /// template<typename U> struct Inner;
2152 /// template<typename U> struct Inner<U*> { }; // #1
2153 /// };
2154 ///
2155 /// Outer<float>::Inner<int*> ii;
2156 /// \endcode
2157 ///
2158 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2159 /// end up instantiating the partial specialization
2160 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
2161 /// template partial specialization \c Outer<T>::Inner<U*>. Given
2162 /// \c Outer<float>::Inner<U*>, this function would return
2163 /// \c Outer<T>::Inner<U*>.
2165 const auto *First =
2166 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2167 return First->InstantiatedFromMember.getPointer();
2168 }
2172 }
2173
2176 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2177 First->InstantiatedFromMember.setPointer(PartialSpec);
2178 }
2179
2180 /// Determines whether this class template partial specialization
2181 /// template was a specialization of a member partial specialization.
2182 ///
2183 /// In the following example, the member template partial specialization
2184 /// \c X<int>::Inner<T*> is a member specialization.
2185 ///
2186 /// \code
2187 /// template<typename T>
2188 /// struct X {
2189 /// template<typename U> struct Inner;
2190 /// template<typename U> struct Inner<U*>;
2191 /// };
2192 ///
2193 /// template<> template<typename T>
2194 /// struct X<int>::Inner<T*> { /* ... */ };
2195 /// \endcode
2197 const auto *First =
2198 cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2199 return First->InstantiatedFromMember.getInt();
2200 }
2201
2202 /// Note that this member template is a specialization.
2204 auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2205 assert(First->InstantiatedFromMember.getPointer() &&
2206 "Only member templates can be member template specializations");
2207 return First->InstantiatedFromMember.setInt(true);
2208 }
2209
2210 /// Retrieves the injected specialization type for this partial
2211 /// specialization. This is not the same as the type-decl-type for
2212 /// this partial specialization, which is an InjectedClassNameType.
2214 assert(getTypeForDecl() && "partial specialization has no type set!");
2215 return cast<InjectedClassNameType>(getTypeForDecl())
2216 ->getInjectedSpecializationType();
2217 }
2218
2219 void Profile(llvm::FoldingSetNodeID &ID) const {
2221 getASTContext());
2222 }
2223
2224 static void
2225 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
2226 TemplateParameterList *TPL, const ASTContext &Context);
2227
2228 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2229
2230 static bool classofKind(Kind K) {
2231 return K == ClassTemplatePartialSpecialization;
2232 }
2233};
2234
2235/// Declaration of a class template.
2237protected:
2238 /// Data that is common to all of the declarations of a given
2239 /// class template.
2241 /// The class template specializations for this class
2242 /// template, including explicit specializations and instantiations.
2243 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
2244
2245 /// The class template partial specializations for this class
2246 /// template.
2247 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
2249
2250 /// The injected-class-name type for this class template.
2252
2253 Common() = default;
2254 };
2255
2256 /// Retrieve the set of specializations of this class template.
2257 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
2258 getSpecializations() const;
2259
2260 /// Retrieve the set of partial specializations of this class
2261 /// template.
2262 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
2264
2267 NamedDecl *Decl)
2268 : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
2269
2270 CommonBase *newCommon(ASTContext &C) const override;
2271
2273 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2274 }
2275
2278 }
2279
2280public:
2281
2282 friend class ASTDeclReader;
2283 friend class ASTDeclWriter;
2285
2286 /// Load any lazily-loaded specializations from the external source.
2287 void LoadLazySpecializations() const;
2288
2289 /// Get the underlying class declarations of the template.
2291 return static_cast<CXXRecordDecl *>(TemplatedDecl);
2292 }
2293
2294 /// Returns whether this template declaration defines the primary
2295 /// class pattern.
2298 }
2299
2300 /// \brief Create a class template node.
2303 DeclarationName Name,
2304 TemplateParameterList *Params,
2305 NamedDecl *Decl);
2306
2307 /// Create an empty class template node.
2309
2310 /// Return the specialization with the provided arguments if it exists,
2311 /// otherwise return the insertion point.
2313 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
2314
2315 /// Insert the specified specialization knowing that it is not already
2316 /// in. InsertPos must be obtained from findSpecialization.
2317 void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
2318
2320 return cast<ClassTemplateDecl>(
2322 }
2324 return cast<ClassTemplateDecl>(
2326 }
2327
2328 /// Retrieve the previous declaration of this class template, or
2329 /// nullptr if no such declaration exists.
2331 return cast_or_null<ClassTemplateDecl>(
2332 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2333 }
2335 return cast_or_null<ClassTemplateDecl>(
2336 static_cast<const RedeclarableTemplateDecl *>(
2337 this)->getPreviousDecl());
2338 }
2339
2341 return cast<ClassTemplateDecl>(
2342 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
2343 }
2345 return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
2346 }
2347
2349 return cast_or_null<ClassTemplateDecl>(
2351 }
2352
2353 /// Return the partial specialization with the provided arguments if it
2354 /// exists, otherwise return the insertion point.
2357 TemplateParameterList *TPL, void *&InsertPos);
2358
2359 /// Insert the specified partial specialization knowing that it is not
2360 /// already in. InsertPos must be obtained from findPartialSpecialization.
2362 void *InsertPos);
2363
2364 /// Retrieve the partial specializations as an ordered list.
2367
2368 /// Find a class template partial specialization with the given
2369 /// type T.
2370 ///
2371 /// \param T a dependent type that names a specialization of this class
2372 /// template.
2373 ///
2374 /// \returns the class template partial specialization that exactly matches
2375 /// the type \p T, or nullptr if no such partial specialization exists.
2377
2378 /// Find a class template partial specialization which was instantiated
2379 /// from the given member partial specialization.
2380 ///
2381 /// \param D a member class template partial specialization.
2382 ///
2383 /// \returns the class template partial specialization which was instantiated
2384 /// from the given member partial specialization, or nullptr if no such
2385 /// partial specialization exists.
2389
2390 /// Retrieve the template specialization type of the
2391 /// injected-class-name for this class template.
2392 ///
2393 /// The injected-class-name for a class template \c X is \c
2394 /// X<template-args>, where \c template-args is formed from the
2395 /// template arguments that correspond to the template parameters of
2396 /// \c X. For example:
2397 ///
2398 /// \code
2399 /// template<typename T, int N>
2400 /// struct array {
2401 /// typedef array this_type; // "array" is equivalent to "array<T, N>"
2402 /// };
2403 /// \endcode
2405
2407 using spec_range = llvm::iterator_range<spec_iterator>;
2408
2410 return spec_range(spec_begin(), spec_end());
2411 }
2412
2414 return makeSpecIterator(getSpecializations(), false);
2415 }
2416
2418 return makeSpecIterator(getSpecializations(), true);
2419 }
2420
2421 // Implement isa/cast/dyncast support
2422 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2423 static bool classofKind(Kind K) { return K == ClassTemplate; }
2424};
2425
2426/// Declaration of a friend template.
2427///
2428/// For example:
2429/// \code
2430/// template <typename T> class A {
2431/// friend class MyVector<T>; // not a friend template
2432/// template <typename U> friend class B; // not a friend template
2433/// template <typename U> friend class Foo<T>::Nested; // friend template
2434/// };
2435/// \endcode
2436///
2437/// \note This class is not currently in use. All of the above
2438/// will yield a FriendDecl, not a FriendTemplateDecl.
2439class FriendTemplateDecl : public Decl {
2440 virtual void anchor();
2441
2442public:
2443 using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
2444
2445private:
2446 // The number of template parameters; always non-zero.
2447 unsigned NumParams = 0;
2448
2449 // The parameter list.
2450 TemplateParameterList **Params = nullptr;
2451
2452 // The declaration that's a friend of this class.
2453 FriendUnion Friend;
2454
2455 // Location of the 'friend' specifier.
2456 SourceLocation FriendLoc;
2457
2459 TemplateParameterList **Params, unsigned NumParams,
2460 FriendUnion Friend, SourceLocation FriendLoc)
2461 : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
2462 Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
2463
2464 FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
2465
2466public:
2467 friend class ASTDeclReader;
2468
2469 static FriendTemplateDecl *
2470 Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
2472 SourceLocation FriendLoc);
2473
2475
2476 /// If this friend declaration names a templated type (or
2477 /// a dependent member type of a templated type), return that
2478 /// type; otherwise return null.
2480 return Friend.dyn_cast<TypeSourceInfo*>();
2481 }
2482
2483 /// If this friend declaration names a templated function (or
2484 /// a member function of a templated type), return that type;
2485 /// otherwise return null.
2487 return Friend.dyn_cast<NamedDecl*>();
2488 }
2489
2490 /// Retrieves the location of the 'friend' keyword.
2492 return FriendLoc;
2493 }
2494
2496 assert(i <= NumParams);
2497 return Params[i];
2498 }
2499
2500 unsigned getNumTemplateParameters() const {
2501 return NumParams;
2502 }
2503
2504 // Implement isa/cast/dyncast/etc.
2505 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2506 static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
2507};
2508
2509/// Declaration of an alias template.
2510///
2511/// For example:
2512/// \code
2513/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
2514/// \endcode
2516protected:
2518
2521 NamedDecl *Decl)
2522 : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
2523 Decl) {}
2524
2525 CommonBase *newCommon(ASTContext &C) const override;
2526
2528 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
2529 }
2530
2531public:
2532 friend class ASTDeclReader;
2533 friend class ASTDeclWriter;
2534
2535 /// Get the underlying function declaration of the template.
2537 return static_cast<TypeAliasDecl *>(TemplatedDecl);
2538 }
2539
2540
2542 return cast<TypeAliasTemplateDecl>(
2544 }
2546 return cast<TypeAliasTemplateDecl>(
2548 }
2549
2550 /// Retrieve the previous declaration of this function template, or
2551 /// nullptr if no such declaration exists.
2553 return cast_or_null<TypeAliasTemplateDecl>(
2554 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
2555 }
2557 return cast_or_null<TypeAliasTemplateDecl>(
2558 static_cast<const RedeclarableTemplateDecl *>(
2559 this)->getPreviousDecl());
2560 }
2561
2563 return cast_or_null<TypeAliasTemplateDecl>(
2565 }
2566
2567 /// Create a function template node.
2570 DeclarationName Name,
2571 TemplateParameterList *Params,
2572 NamedDecl *Decl);
2573
2574 /// Create an empty alias template node.
2577
2578 // Implement isa/cast/dyncast support
2579 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2580 static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
2581};
2582
2583/// Represents a variable template specialization, which refers to
2584/// a variable template with a given set of template arguments.
2585///
2586/// Variable template specializations represent both explicit
2587/// specializations of variable templates, as in the example below, and
2588/// implicit instantiations of variable templates.
2589///
2590/// \code
2591/// template<typename T> constexpr T pi = T(3.1415926535897932385);
2592///
2593/// template<>
2594/// constexpr float pi<float>; // variable template specialization pi<float>
2595/// \endcode
2597 public llvm::FoldingSetNode {
2598
2599 /// Structure that stores information about a variable template
2600 /// specialization that was instantiated from a variable template partial
2601 /// specialization.
2602 struct SpecializedPartialSpecialization {
2603 /// The variable template partial specialization from which this
2604 /// variable template specialization was instantiated.
2605 VarTemplatePartialSpecializationDecl *PartialSpecialization;
2606
2607 /// The template argument list deduced for the variable template
2608 /// partial specialization itself.
2609 const TemplateArgumentList *TemplateArgs;
2610 };
2611
2612 /// The template that this specialization specializes.
2613 llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
2614 SpecializedTemplate;
2615
2616 /// Further info for explicit template specialization/instantiation.
2617 struct ExplicitSpecializationInfo {
2618 /// The type-as-written.
2619 TypeSourceInfo *TypeAsWritten = nullptr;
2620
2621 /// The location of the extern keyword.
2622 SourceLocation ExternLoc;
2623
2624 /// The location of the template keyword.
2625 SourceLocation TemplateKeywordLoc;
2626
2627 ExplicitSpecializationInfo() = default;
2628 };
2629
2630 /// Further info for explicit template specialization/instantiation.
2631 /// Does not apply to implicit specializations.
2632 ExplicitSpecializationInfo *ExplicitInfo = nullptr;
2633
2634 /// The template arguments used to describe this specialization.
2635 const TemplateArgumentList *TemplateArgs;
2636 const ASTTemplateArgumentListInfo *TemplateArgsInfo = nullptr;
2637
2638 /// The point where this template was instantiated (if any).
2639 SourceLocation PointOfInstantiation;
2640
2641 /// The kind of specialization this declaration refers to.
2642 LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
2643 unsigned SpecializationKind : 3;
2644
2645 /// Whether this declaration is a complete definition of the
2646 /// variable template specialization. We can't otherwise tell apart
2647 /// an instantiated declaration from an instantiated definition with
2648 /// no initializer.
2649 LLVM_PREFERRED_TYPE(bool)
2650 unsigned IsCompleteDefinition : 1;
2651
2652protected:
2654 SourceLocation StartLoc, SourceLocation IdLoc,
2655 VarTemplateDecl *SpecializedTemplate,
2656 QualType T, TypeSourceInfo *TInfo,
2657 StorageClass S,
2659
2660 explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
2661
2662public:
2663 friend class ASTDeclReader;
2664 friend class ASTDeclWriter;
2665 friend class VarDecl;
2666
2668 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2669 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
2670 TypeSourceInfo *TInfo, StorageClass S,
2674
2675 void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
2676 bool Qualified) const override;
2677
2679 VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
2680 return cast<VarTemplateSpecializationDecl>(Recent);
2681 }
2682
2683 /// Retrieve the template that this specialization specializes.
2685
2686 /// Retrieve the template arguments of the variable template
2687 /// specialization.
2688 const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
2689
2690 // TODO: Always set this when creating the new specialization?
2691 void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
2693
2695 return TemplateArgsInfo;
2696 }
2697
2698 /// Determine the kind of specialization that this
2699 /// declaration represents.
2701 return static_cast<TemplateSpecializationKind>(SpecializationKind);
2702 }
2703
2706 }
2707
2709 return isExplicitSpecialization() &&
2710 isa<CXXRecordDecl>(getLexicalDeclContext());
2711 }
2712
2713 /// True if this declaration is an explicit specialization,
2714 /// explicit instantiation declaration, or explicit instantiation
2715 /// definition.
2719 }
2720
2722 SpecializationKind = TSK;
2723 }
2724
2725 /// Get the point of instantiation (if any), or null if none.
2727 return PointOfInstantiation;
2728 }
2729
2731 assert(Loc.isValid() && "point of instantiation must be valid!");
2732 PointOfInstantiation = Loc;
2733 }
2734
2735 void setCompleteDefinition() { IsCompleteDefinition = true; }
2736
2737 /// If this variable template specialization is an instantiation of
2738 /// a template (rather than an explicit specialization), return the
2739 /// variable template or variable template partial specialization from which
2740 /// it was instantiated.
2741 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2744 return llvm::PointerUnion<VarTemplateDecl *,
2746
2748 }
2749
2750 /// Retrieve the variable template or variable template partial
2751 /// specialization which was specialized by this.
2752 llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2754 if (const auto *PartialSpec =
2755 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2756 return PartialSpec->PartialSpecialization;
2757
2758 return SpecializedTemplate.get<VarTemplateDecl *>();
2759 }
2760
2761 /// Retrieve the set of template arguments that should be used
2762 /// to instantiate the initializer of the variable template or variable
2763 /// template partial specialization from which this variable template
2764 /// specialization was instantiated.
2765 ///
2766 /// \returns For a variable template specialization instantiated from the
2767 /// primary template, this function will return the same template arguments
2768 /// as getTemplateArgs(). For a variable template specialization instantiated
2769 /// from a variable template partial specialization, this function will the
2770 /// return deduced template arguments for the variable template partial
2771 /// specialization itself.
2773 if (const auto *PartialSpec =
2774 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2775 return *PartialSpec->TemplateArgs;
2776
2777 return getTemplateArgs();
2778 }
2779
2780 /// Note that this variable template specialization is actually an
2781 /// instantiation of the given variable template partial specialization whose
2782 /// template arguments have been deduced.
2784 const TemplateArgumentList *TemplateArgs) {
2785 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2786 "Already set to a variable template partial specialization!");
2787 auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
2788 PS->PartialSpecialization = PartialSpec;
2789 PS->TemplateArgs = TemplateArgs;
2790 SpecializedTemplate = PS;
2791 }
2792
2793 /// Note that this variable template specialization is an instantiation
2794 /// of the given variable template.
2796 assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
2797 "Previously set to a variable template partial specialization!");
2798 SpecializedTemplate = TemplDecl;
2799 }
2800
2801 /// Sets the type of this specialization as it was written by
2802 /// the user.
2804 if (!ExplicitInfo)
2805 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2806 ExplicitInfo->TypeAsWritten = T;
2807 }
2808
2809 /// Gets the type of this specialization as it was written by
2810 /// the user, if it was so written.
2812 return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
2813 }
2814
2815 /// Gets the location of the extern keyword, if present.
2817 return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
2818 }
2819
2820 /// Sets the location of the extern keyword.
2822 if (!ExplicitInfo)
2823 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2824 ExplicitInfo->ExternLoc = Loc;
2825 }
2826
2827 /// Sets the location of the template keyword.
2829 if (!ExplicitInfo)
2830 ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
2831 ExplicitInfo->TemplateKeywordLoc = Loc;
2832 }
2833
2834 /// Gets the location of the template keyword, if present.
2836 return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
2837 }
2838
2839 SourceRange getSourceRange() const override LLVM_READONLY;
2840
2841 void Profile(llvm::FoldingSetNodeID &ID) const {
2842 Profile(ID, TemplateArgs->asArray(), getASTContext());
2843 }
2844
2845 static void Profile(llvm::FoldingSetNodeID &ID,
2846 ArrayRef<TemplateArgument> TemplateArgs,
2847 const ASTContext &Context) {
2848 ID.AddInteger(TemplateArgs.size());
2849 for (const TemplateArgument &TemplateArg : TemplateArgs)
2850 TemplateArg.Profile(ID, Context);
2851 }
2852
2853 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2854
2855 static bool classofKind(Kind K) {
2856 return K >= firstVarTemplateSpecialization &&
2857 K <= lastVarTemplateSpecialization;
2858 }
2859};
2860
2863 /// The list of template parameters
2864 TemplateParameterList *TemplateParams = nullptr;
2865
2866 /// The source info for the template arguments as written.
2867 /// FIXME: redundant with TypeAsWritten?
2868 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
2869
2870 /// The variable template partial specialization from which this
2871 /// variable template partial specialization was instantiated.
2872 ///
2873 /// The boolean value will be true to indicate that this variable template
2874 /// partial specialization was specialized at this level.
2875 llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
2876 InstantiatedFromMember;
2877
2879 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2881 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
2883 const ASTTemplateArgumentListInfo *ArgInfos);
2884
2886 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
2887 Context),
2888 InstantiatedFromMember(nullptr, false) {}
2889
2890 void anchor() override;
2891
2892public:
2893 friend class ASTDeclReader;
2894 friend class ASTDeclWriter;
2895
2897 Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
2899 VarTemplateDecl *SpecializedTemplate, QualType T,
2901 const TemplateArgumentListInfo &ArgInfos);
2902
2905
2907 return cast<VarTemplatePartialSpecializationDecl>(
2908 static_cast<VarTemplateSpecializationDecl *>(
2909 this)->getMostRecentDecl());
2910 }
2911
2912 /// Get the list of template parameters
2914 return TemplateParams;
2915 }
2916
2917 /// Get the template arguments as written.
2919 return ArgsAsWritten;
2920 }
2921
2922 /// \brief All associated constraints of this partial specialization,
2923 /// including the requires clause and any constraints derived from
2924 /// constrained-parameters.
2925 ///
2926 /// The constraints in the resulting list are to be treated as if in a
2927 /// conjunction ("and").
2929 TemplateParams->getAssociatedConstraints(AC);
2930 }
2931
2933 return TemplateParams->hasAssociatedConstraints();
2934 }
2935
2936 /// \brief Retrieve the member variable template partial specialization from
2937 /// which this particular variable template partial specialization was
2938 /// instantiated.
2939 ///
2940 /// \code
2941 /// template<typename T>
2942 /// struct Outer {
2943 /// template<typename U> U Inner;
2944 /// template<typename U> U* Inner<U*> = (U*)(0); // #1
2945 /// };
2946 ///
2947 /// template int* Outer<float>::Inner<int*>;
2948 /// \endcode
2949 ///
2950 /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
2951 /// end up instantiating the partial specialization
2952 /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
2953 /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
2954 /// \c Outer<float>::Inner<U*>, this function would return
2955 /// \c Outer<T>::Inner<U*>.
2957 const auto *First =
2958 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2959 return First->InstantiatedFromMember.getPointer();
2960 }
2961
2962 void
2964 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2965 First->InstantiatedFromMember.setPointer(PartialSpec);
2966 }
2967
2968 /// Determines whether this variable template partial specialization
2969 /// was a specialization of a member partial specialization.
2970 ///
2971 /// In the following example, the member template partial specialization
2972 /// \c X<int>::Inner<T*> is a member specialization.
2973 ///
2974 /// \code
2975 /// template<typename T>
2976 /// struct X {
2977 /// template<typename U> U Inner;
2978 /// template<typename U> U* Inner<U*> = (U*)(0);
2979 /// };
2980 ///
2981 /// template<> template<typename T>
2982 /// U* X<int>::Inner<T*> = (T*)(0) + 1;
2983 /// \endcode
2985 const auto *First =
2986 cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2987 return First->InstantiatedFromMember.getInt();
2988 }
2989
2990 /// Note that this member template is a specialization.
2992 auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2993 assert(First->InstantiatedFromMember.getPointer() &&
2994 "Only member templates can be member template specializations");
2995 return First->InstantiatedFromMember.setInt(true);
2996 }
2997
2998 SourceRange getSourceRange() const override LLVM_READONLY;
2999
3000 void Profile(llvm::FoldingSetNodeID &ID) const {
3002 getASTContext());
3003 }
3004
3005 static void
3006 Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
3007 TemplateParameterList *TPL, const ASTContext &Context);
3008
3009 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3010
3011 static bool classofKind(Kind K) {
3012 return K == VarTemplatePartialSpecialization;
3013 }
3014};
3015
3016/// Declaration of a variable template.
3018protected:
3019 /// Data that is common to all of the declarations of a given
3020 /// variable template.
3022 /// The variable template specializations for this variable
3023 /// template, including explicit specializations and instantiations.
3024 llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
3025
3026 /// The variable template partial specializations for this variable
3027 /// template.
3028 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
3030
3031 Common() = default;
3032 };
3033
3034 /// Retrieve the set of specializations of this variable template.
3035 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
3036 getSpecializations() const;
3037
3038 /// Retrieve the set of partial specializations of this class
3039 /// template.
3040 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
3042
3045 NamedDecl *Decl)
3046 : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
3047
3048 CommonBase *newCommon(ASTContext &C) const override;
3049
3051 return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
3052 }
3053
3054public:
3055 friend class ASTDeclReader;
3056 friend class ASTDeclWriter;
3057
3058 /// Load any lazily-loaded specializations from the external source.
3059 void LoadLazySpecializations() const;
3060
3061 /// Get the underlying variable declarations of the template.
3063 return static_cast<VarDecl *>(TemplatedDecl);
3064 }
3065
3066 /// Returns whether this template declaration defines the primary
3067 /// variable pattern.
3070 }
3071
3073
3074 /// Create a variable template node.
3077 TemplateParameterList *Params,
3078 VarDecl *Decl);
3079
3080 /// Create an empty variable template node.
3082
3083 /// Return the specialization with the provided arguments if it exists,
3084 /// otherwise return the insertion point.
3086 findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
3087
3088 /// Insert the specified specialization knowing that it is not already
3089 /// in. InsertPos must be obtained from findSpecialization.
3090 void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
3091
3093 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3094 }
3096 return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
3097 }
3098
3099 /// Retrieve the previous declaration of this variable template, or
3100 /// nullptr if no such declaration exists.
3102 return cast_or_null<VarTemplateDecl>(
3103 static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
3104 }
3106 return cast_or_null<VarTemplateDecl>(
3107 static_cast<const RedeclarableTemplateDecl *>(
3108 this)->getPreviousDecl());
3109 }
3110
3112 return cast<VarTemplateDecl>(
3113 static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
3114 }
3116 return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
3117 }
3118
3120 return cast_or_null<VarTemplateDecl>(
3122 }
3123
3124 /// Return the partial specialization with the provided arguments if it
3125 /// exists, otherwise return the insertion point.
3128 TemplateParameterList *TPL, void *&InsertPos);
3129
3130 /// Insert the specified partial specialization knowing that it is not
3131 /// already in. InsertPos must be obtained from findPartialSpecialization.
3133 void *InsertPos);
3134
3135 /// Retrieve the partial specializations as an ordered list.
3138
3139 /// Find a variable template partial specialization which was
3140 /// instantiated
3141 /// from the given member partial specialization.
3142 ///
3143 /// \param D a member variable template partial specialization.
3144 ///
3145 /// \returns the variable template partial specialization which was
3146 /// instantiated
3147 /// from the given member partial specialization, or nullptr if no such
3148 /// partial specialization exists.
3151
3153 using spec_range = llvm::iterator_range<spec_iterator>;
3154
3156 return spec_range(spec_begin(), spec_end());
3157 }
3158
3160 return makeSpecIterator(getSpecializations(), false);
3161 }
3162
3164 return makeSpecIterator(getSpecializations(), true);
3165 }
3166
3167 // Implement isa/cast/dyncast support
3168 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3169 static bool classofKind(Kind K) { return K == VarTemplate; }
3170};
3171
3172/// Declaration of a C++20 concept.
3173class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
3174protected:
3176
3179 : TemplateDecl(Concept, DC, L, Name, Params),
3181public:
3184 TemplateParameterList *Params,
3187
3189 return ConstraintExpr;
3190 }
3191
3192 SourceRange getSourceRange() const override LLVM_READONLY {
3193 return SourceRange(getTemplateParameters()->getTemplateLoc(),
3195 }
3196
3197 bool isTypeConcept() const {
3198 return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
3199 }
3200
3202 return cast<ConceptDecl>(getPrimaryMergedDecl(this));
3203 }
3205 return const_cast<ConceptDecl *>(this)->getCanonicalDecl();
3206 }
3207
3208 // Implement isa/cast/dyncast/etc.
3209 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3210 static bool classofKind(Kind K) { return K == Concept; }
3211
3212 friend class ASTReader;
3213 friend class ASTDeclReader;
3214 friend class ASTDeclWriter;
3215};
3216
3217// An implementation detail of ConceptSpecialicationExpr that holds the template
3218// arguments, so we can later use this to reconstitute the template arguments
3219// during constraint checking.
3221 : public Decl,
3222 private llvm::TrailingObjects<ImplicitConceptSpecializationDecl,
3223 TemplateArgument> {
3224 unsigned NumTemplateArgs;
3225
3227 ArrayRef<TemplateArgument> ConvertedArgs);
3228 ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs);
3229
3230public:
3233 ArrayRef<TemplateArgument> ConvertedArgs);
3236 unsigned NumTemplateArgs);
3237
3239 return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
3240 NumTemplateArgs);
3241 }
3243
3244 static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; }
3245 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3246
3248 friend class ASTDeclReader;
3249};
3250
3251/// A template parameter object.
3252///
3253/// Template parameter objects represent values of class type used as template
3254/// arguments. There is one template parameter object for each such distinct
3255/// value used as a template argument across the program.
3256///
3257/// \code
3258/// struct A { int x, y; };
3259/// template<A> struct S;
3260/// S<A{1, 2}> s1;
3261/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
3262/// \endcode
3264 public Mergeable<TemplateParamObjectDecl>,
3265 public llvm::FoldingSetNode {
3266private:
3267 /// The value of this template parameter object.
3268 APValue Value;
3269
3271 : ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
3272 T),
3273 Value(V) {}
3274
3276 const APValue &V);
3277 static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
3279
3280 /// Only ASTContext::getTemplateParamObjectDecl and deserialization
3281 /// create these.
3282 friend class ASTContext;
3283 friend class ASTReader;
3284 friend class ASTDeclReader;
3285
3286public:
3287 /// Print this template parameter object in a human-readable format.
3288 void printName(llvm::raw_ostream &OS,
3289 const PrintingPolicy &Policy) const override;
3290
3291 /// Print this object as an equivalent expression.
3292 void printAsExpr(llvm::raw_ostream &OS) const;
3293 void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3294
3295 /// Print this object as an initializer suitable for a variable of the
3296 /// object's type.
3297 void printAsInit(llvm::raw_ostream &OS) const;
3298 void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
3299
3300 const APValue &getValue() const { return Value; }
3301
3302 static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
3303 const APValue &V) {
3304 ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
3305 V.Profile(ID);
3306 }
3307 void Profile(llvm::FoldingSetNodeID &ID) {
3308 Profile(ID, getType(), getValue());
3309 }
3310
3312 return getFirstDecl();
3313 }
3315 return getFirstDecl();
3316 }
3317
3318 static bool classof(const Decl *D) { return classofKind(D->getKind()); }
3319 static bool classofKind(Kind K) { return K == TemplateParamObject; }
3320};
3321
3323 if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
3324 return PD;
3325 if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl *>())
3326 return PD;
3327 return P.get<TemplateTemplateParmDecl *>();
3328}
3329
3331 auto *TD = dyn_cast<TemplateDecl>(D);
3332 return TD && (isa<ClassTemplateDecl>(TD) ||
3333 isa<ClassTemplatePartialSpecializationDecl>(TD) ||
3334 isa<TypeAliasTemplateDecl>(TD) ||
3335 isa<TemplateTemplateParmDecl>(TD))
3336 ? TD
3337 : nullptr;
3338}
3339
3340/// Check whether the template parameter is a pack expansion, and if so,
3341/// determine the number of parameters produced by that expansion. For instance:
3342///
3343/// \code
3344/// template<typename ...Ts> struct A {
3345/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
3346/// };
3347/// \endcode
3348///
3349/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
3350/// is not a pack expansion, so returns an empty Optional.
3351inline std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
3352 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
3353 if (TTP->isExpandedParameterPack())
3354 return TTP->getNumExpansionParameters();
3355 }
3356
3357 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
3358 if (NTTP->isExpandedParameterPack())
3359 return NTTP->getNumExpansionTypes();
3360 }
3361
3362 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
3363 if (TTP->isExpandedParameterPack())
3364 return TTP->getNumExpansionTemplateParameters();
3365 }
3366
3367 return std::nullopt;
3368}
3369
3370/// Internal helper used by Subst* nodes to retrieve the parameter list
3371/// for their AssociatedDecl.
3372TemplateParameterList *getReplacedTemplateParameterList(Decl *D);
3373
3374} // namespace clang
3375
3376#endif // LLVM_CLANG_AST_DECLTEMPLATE_H
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3284
int Id
Definition: ASTDiff.cpp:190
StringRef P
static char ID
Definition: Arena.cpp:183
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
C Language Family Type Representation.
__device__ int
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:366
bool isConstrained() const
Definition: Type.h:5996
Represents the builtin template declaration which is used to implement __make_integer_seq and other b...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
BuiltinTemplateKind getBuiltinTemplateKind() const
static BuiltinTemplateDecl * Create(const ASTContext &C, DeclContext *DC, DeclarationName Name, BuiltinTemplateKind BTK)
static bool classof(const Decl *D)
static bool classofKind(Kind K)
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CXXRecordDecl * getMostRecentNonInjectedDecl()
Definition: DeclCXX.h:549
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
Definition: DeclCXX.cpp:1905
Declaration of a class template.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
ClassTemplateDecl * getMostRecentDecl()
spec_iterator spec_begin() const
spec_iterator spec_end() const
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
static bool classofKind(Kind K)
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
CommonBase * newCommon(ASTContext &C) const override
llvm::iterator_range< spec_iterator > spec_range
static bool classof(const Decl *D)
const ClassTemplateDecl * getMostRecentDecl() const
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
const ClassTemplateDecl * getCanonicalDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary class pattern.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
ClassTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this class template, or nullptr if no such declaration exists.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
const ClassTemplateDecl * getPreviousDecl() const
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
void setCommonPtr(Common *C)
spec_range specializations() const
QualType getInjectedClassNameSpecialization()
Retrieve the template specialization type of the injected-class-name for this class template.
Common * getCommonPtr() const
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMemberTemplate() const
ClassTemplatePartialSpecializationDecl * getMostRecentDecl()
void setInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *PartialSpec)
bool isMemberSpecialization()
Determines whether this class template partial specialization template was a specialization of a memb...
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void Profile(llvm::FoldingSetNodeID &ID) const
void setMemberSpecialization()
Note that this member template is a specialization.
QualType getInjectedSpecializationType() const
Retrieves the injected specialization type for this partial specialization.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Get the template arguments as written.
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isClassScopeExplicitSpecialization() const
Is this an explicit specialization at class scope (within the class that owns the primary template)?...
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
SourceLocation getExternLoc() const
Gets the location of the extern keyword, if present.
ClassTemplateSpecializationDecl * getMostRecentDecl()
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void setTemplateArgs(TemplateArgumentList *Args)
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
void setTypeAsWritten(TypeSourceInfo *T)
Sets the type of this specialization as it was written by the user.
void setPointOfInstantiation(SourceLocation Loc)
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
TypeSourceInfo * getTypeAsWritten() const
Gets the type of this specialization as it was written by the user, if it was so written.
static bool classof(const Decl *D)
void setSpecializationKind(TemplateSpecializationKind TSK)
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
void setInstantiationOf(ClassTemplateDecl *TemplDecl)
Note that this class template specialization is an instantiation of the given class template.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate members of the class templa...
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this class template specialization is an instantiation of a template (rather than an explicit spec...
void setExternLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this class template specialization is actually an instantiation of the given class template...
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
void Profile(llvm::FoldingSetNodeID &ID) const
void setSpecializedTemplate(ClassTemplateDecl *Specialized)
Declaration of a C++20 concept.
Expr * getConstraintExpr() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
bool isTypeConcept() const
ConceptDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
static bool classof(const Decl *D)
const ConceptDecl * getCanonicalDecl() const
static bool classofKind(Kind K)
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:128
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:599
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:89
SourceLocation getLocation() const
Definition: DeclBase.h:445
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:908
Kind getKind() const
Definition: DeclBase.h:448
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:433
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:770
Storage for a default argument.
Definition: DeclTemplate.h:299
void setInherited(const ASTContext &C, ParmDecl *InheritedFrom)
Set that the default argument was inherited from another parameter.
Definition: DeclTemplate.h:360
bool isSet() const
Determine whether there is a default argument for this parameter.
Definition: DeclTemplate.h:326
ArgType get() const
Get the default argument's value.
Definition: DeclTemplate.h:334
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:354
void clear()
Remove the default argument, even if it was inherited.
Definition: DeclTemplate.h:380
const ParmDecl * getInheritedFrom() const
Get the parameter from which we inherit the default argument, if any.
Definition: DeclTemplate.h:345
bool isInherited() const
Determine whether the default argument for this parameter was inherited from a previous declaration o...
Definition: DeclTemplate.h:330
Provides information about a dependent function-template specialization declaration.
Definition: DeclTemplate.h:690
ArrayRef< FunctionTemplateDecl * > getCandidates() const
Returns the candidates for the primary function template.
Definition: DeclTemplate.h:709
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
Definition: DeclTemplate.h:702
This represents one expression.
Definition: Expr.h:110
Stores a list of template parameters and the associated requires-clause (if any) for a TemplateDecl a...
Definition: DeclTemplate.h:222
FixedSizeTemplateParameterListStorage(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Definition: DeclTemplate.h:229
Declaration of a friend template.
static bool classof(const Decl *D)
SourceLocation getFriendLoc() const
Retrieves the location of the 'friend' keyword.
NamedDecl * getFriendDecl() const
If this friend declaration names a templated function (or a member function of a templated type),...
TemplateParameterList * getTemplateParameterList(unsigned i) const
static bool classofKind(Kind K)
unsigned getNumTemplateParameters() const
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TypeSourceInfo * getFriendType() const
If this friend declaration names a templated type (or a dependent member type of a templated type),...
Represents a function declaration or definition.
Definition: Decl.h:1971
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2284
Declaration of a template function.
Definition: DeclTemplate.h:958
FunctionTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
spec_iterator spec_end() const
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
CommonBase * newCommon(ASTContext &C) const override
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
FunctionTemplateDecl * getInstantiatedFromMemberTemplate() const
Common * getCommonPtr() const
Definition: DeclTemplate.h:980
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary pattern.
const FunctionTemplateDecl * getPreviousDecl() const
bool isAbbreviated() const
Return whether this function template is an abbreviated function template, e.g.
FunctionTemplateDecl * getMostRecentDecl()
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
const FunctionTemplateDecl * getCanonicalDecl() const
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
spec_range specializations() const
spec_iterator spec_begin() const
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Definition: DeclTemplate.h:972
const FunctionTemplateDecl * getMostRecentDecl() const
llvm::iterator_range< spec_iterator > spec_range
static bool classofKind(Kind K)
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
static bool classof(const Decl *D)
Provides information about a function template specialization, which is a FunctionDecl that has been ...
Definition: DeclTemplate.h:467
const TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
Definition: DeclTemplate.h:481
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:543
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
Definition: DeclTemplate.h:605
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
Definition: DeclTemplate.h:523
MemberSpecializationInfo * getMemberSpecializationInfo() const
Get the specialization info if this function template specialization is also a member specialization:
Definition: DeclTemplate.h:594
const ASTTemplateArgumentListInfo * TemplateArgumentsAsWritten
The template arguments as written in the sources, if provided.
Definition: DeclTemplate.h:485
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this function template specialization.
Definition: DeclTemplate.h:554
void Profile(llvm::FoldingSetNodeID &ID)
Definition: DeclTemplate.h:600
SourceLocation PointOfInstantiation
The point at which this function template specialization was first instantiated.
Definition: DeclTemplate.h:489
FunctionDecl * getFunction() const
Retrieve the declaration of the function template specialization.
Definition: DeclTemplate.h:520
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:526
void setPointOfInstantiation(SourceLocation POI)
Set the (first) point of instantiation of this function template specialization.
Definition: DeclTemplate.h:560
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
Definition: DeclTemplate.h:537
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
ArrayRef< TemplateArgument > getTemplateArguments() const
static bool classof(const Decl *D)
Provides information a specialization of a member of a class template, which may be a member function...
Definition: DeclTemplate.h:616
void setTemplateSpecializationKind(TemplateSpecializationKind TSK)
Set the template specialization kind.
Definition: DeclTemplate.h:647
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template specialization this is.
Definition: DeclTemplate.h:638
SourceLocation getPointOfInstantiation() const
Retrieve the first point of instantiation of this member.
Definition: DeclTemplate.h:656
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI=SourceLocation())
Definition: DeclTemplate.h:626
void setPointOfInstantiation(SourceLocation POI)
Set the first point of instantiation.
Definition: DeclTemplate.h:661
NamedDecl * getInstantiatedFrom() const
Retrieve the member declaration from which this member was instantiated.
Definition: DeclTemplate.h:635
Provides common interface for the Decls that cannot be redeclared, but can be merged if the same decl...
Definition: Redeclarable.h:314
TemplateParamObjectDecl * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:320
This represents a decl that may have a name.
Definition: Decl.h:249
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool isPackExpansion() const
Whether this parameter pack is a pack expansion.
const DefArgStorage & getDefaultArgStorage() const
QualType getExpansionType(unsigned I) const
Retrieve a particular expansion type within an expanded parameter pack.
static bool classofKind(Kind K)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
TypeSourceInfo * getExpansionTypeSourceInfo(unsigned I) const
Retrieve a particular expansion type source info within an expanded parameter pack.
static bool classof(const Decl *D)
unsigned getNumExpansionTypes() const
Retrieves the number of expansion types in an expanded parameter pack.
bool isExpandedParameterPack() const
Whether this parameter is a non-type template parameter pack that has a known list of different types...
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
Expr * getDefaultArgument() const
Retrieve the default argument, if any.
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the associated-constraints of this template parameter.
void setDefaultArgument(Expr *DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
bool hasPlaceholderTypeConstraint() const
Determine whether this non-type template parameter's type has a placeholder with a type-constraint.
Expr * getPlaceholderTypeConstraint() const
Return the constraint introduced by the placeholder type of this non-type template parameter (if any)...
void setPlaceholderTypeConstraint(Expr *E)
void removeDefaultArgument()
Removes the default argument of this template parameter.
void setInheritedDefaultArgument(const ASTContext &C, NonTypeTemplateParmDecl *Parm)
Represents a pack expansion of types.
Definition: Type.h:6565
A (possibly-)qualified type.
Definition: Type.h:940
Declaration of a redeclarable template.
Definition: DeclTemplate.h:717
static SpecIterator< EntryType > makeSpecIterator(llvm::FoldingSetVector< EntryType > &Specs, bool isEnd)
Definition: DeclTemplate.h:769
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Definition: DeclTemplate.h:824
redeclarable_base::redecl_iterator redecl_iterator
Definition: DeclTemplate.h:926
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
Definition: DeclTemplate.h:861
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments &&...ProfileArgs)
const RedeclarableTemplateDecl * getCanonicalDecl() const
Definition: DeclTemplate.h:839
redeclarable_base::redecl_range redecl_range
Definition: DeclTemplate.h:925
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
Definition: DeclTemplate.h:814
static bool classof(const Decl *D)
Definition: DeclTemplate.h:936
RedeclarableTemplateDecl * getInstantiatedFromMemberTemplate() const
Retrieve the member template from which this template was instantiated, or nullptr if this template w...
Definition: DeclTemplate.h:908
static bool classofKind(Kind K)
Definition: DeclTemplate.h:938
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
Definition: DeclTemplate.h:836
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
void setMemberSpecialization()
Note that this member template is a specialization.
Definition: DeclTemplate.h:866
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD)
Definition: DeclTemplate.h:912
ArrayRef< TemplateArgument > getInjectedTemplateArgs()
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Provides common interface for the Decls that can be redeclared.
Definition: Redeclarable.h:84
RedeclarableTemplateDecl * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:216
RedeclarableTemplateDecl * getNextRedeclaration() const
Definition: Redeclarable.h:189
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:204
llvm::iterator_range< redecl_iterator > redecl_range
Definition: Redeclarable.h:292
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:226
bool isFirstDecl() const
True if this is the first declaration in its redeclaration chain.
Definition: Redeclarable.h:223
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:296
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:457
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:350
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3683
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
A template argument list.
Definition: DeclTemplate.h:244
TemplateArgumentList(const TemplateArgumentList &)=delete
const TemplateArgument * data() const
Retrieve a pointer to the template argument list.
Definition: DeclTemplate.h:283
const TemplateArgument & operator[](unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:271
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Definition: DeclTemplate.h:280
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:265
TemplateArgumentList & operator=(const TemplateArgumentList &)=delete
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:274
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
Definition: TemplateBase.h:61
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
NamedDecl * TemplatedDecl
Definition: DeclTemplate.h:444
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:445
bool isTypeAlias() const
bool hasAssociatedConstraints() const
void init(NamedDecl *NewTemplatedDecl)
Initialize the underlying templated declaration.
Definition: DeclTemplate.h:453
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:426
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:438
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params)
Definition: DeclTemplate.h:404
void setTemplateParameters(TemplateParameterList *TParams)
Definition: DeclTemplate.h:448
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
static bool classof(const Decl *D)
Definition: DeclTemplate.h:432
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
static bool classofKind(Kind K)
Definition: DeclTemplate.h:434
A template parameter object.
TemplateParamObjectDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void printAsExpr(llvm::raw_ostream &OS) const
Print this object as an equivalent expression.
const TemplateParamObjectDecl * getCanonicalDecl() const
void Profile(llvm::FoldingSetNodeID &ID)
const APValue & getValue() const
static bool classof(const Decl *D)
static void Profile(llvm::FoldingSetNodeID &ID, QualType T, const APValue &V)
void printName(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const override
Print this template parameter object in a human-readable format.
void printAsInit(llvm::raw_ostream &OS) const
Print this object as an initializer suitable for a variable of the object's type.
static bool classofKind(Kind K)
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
const_iterator end() const
Definition: DeclTemplate.h:134
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:144
SourceRange getSourceRange() const LLVM_READONLY
Definition: DeclTemplate.h:203
const_iterator begin() const
Definition: DeclTemplate.h:132
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
const Expr * getRequiresClause() const
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:185
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
size_t numTrailingObjects(OverloadToken< Expr * >) const
Definition: DeclTemplate.h:107
bool hasParameterPack() const
Determine whether this template parameter list contains a parameter pack.
Definition: DeclTemplate.h:172
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
NamedDecl *const * const_iterator
Iterates through the template parameters in this list.
Definition: DeclTemplate.h:129
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:180
void print(raw_ostream &Out, const ASTContext &Context, const PrintingPolicy &Policy, bool OmitTemplateKW=false) const
SourceLocation getRAngleLoc() const
Definition: DeclTemplate.h:201
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
const NamedDecl * getParam(unsigned Idx) const
Definition: DeclTemplate.h:148
bool containsUnexpandedParameterPack() const
Determine whether this template parameter list contains an unexpanded parameter pack.
SourceLocation getLAngleLoc() const
Definition: DeclTemplate.h:200
size_t numTrailingObjects(OverloadToken< NamedDecl * >) const
Definition: DeclTemplate.h:103
TemplateParameterList(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
void print(raw_ostream &Out, const ASTContext &Context, bool OmitTemplateKW=false) const
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:139
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:199
ArrayRef< const NamedDecl * > asArray() const
Definition: DeclTemplate.h:140
Defines the position of a template parameter within a template parameter list.
static constexpr unsigned MaxPosition
static constexpr unsigned MaxDepth
unsigned getPosition() const
Get the position of the template parameter within its parameter list.
void setPosition(unsigned P)
unsigned getIndex() const
Get the index of the template parameter within its parameter list.
TemplateParmPosition(unsigned D, unsigned P)
unsigned getDepth() const
Get the nesting depth of the template parameter.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
bool wasDeclaredWithTypename() const
Whether this template template parameter was declared with the 'typename' keyword.
TemplateParameterList * getExpansionTemplateParameters(unsigned I) const
Retrieve a particular expansion type within an expanded parameter pack.
bool isPackExpansion() const
Whether this parameter pack is a pack expansion.
unsigned getNumExpansionTemplateParameters() const
Retrieves the number of expansion template parameters in an expanded parameter pack.
const DefArgStorage & getDefaultArgStorage() const
static bool classof(const Decl *D)
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
void setInheritedDefaultArgument(const ASTContext &C, TemplateTemplateParmDecl *Prev)
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
static bool classofKind(Kind K)
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setDeclaredWithTypename(bool withTypename)
Set whether this template template parameter was declared with the 'typename' or 'class' keyword.
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
bool isExpandedParameterPack() const
Whether this parameter is a template template parameter pack that has a known list of different templ...
void removeDefaultArgument()
Removes the default argument of this template parameter.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
bool wasDeclaredWithTypename() const
Whether this template type parameter was declared with the 'typename' keyword.
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
QualType getDefaultArgument() const
Retrieve the default argument, if any.
unsigned getIndex() const
Retrieve the index of the template parameter.
void setInheritedDefaultArgument(const ASTContext &C, TemplateTypeParmDecl *Prev)
Set that this default argument was inherited from another parameter.
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
bool hasTypeConstraint() const
Determine whether this template parameter has a type-constraint.
TypeSourceInfo * getDefaultArgumentInfo() const
Retrieves the default argument's source information, if any.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isExpandedParameterPack() const
Whether this parameter is a template type parameter pack that has a known list of different type-cons...
void removeDefaultArgument()
Removes the default argument of this template parameter.
void setDefaultArgument(TypeSourceInfo *DefArg)
Set the default argument for this template parameter.
bool isParameterPack() const
Returns whether this is a parameter pack.
unsigned getDepth() const
Retrieve the depth of the template parameter.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
const DefArgStorage & getDefaultArgStorage() const
void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint)
unsigned getNumExpansionParameters() const
Retrieves the number of parameters in an expanded parameter pack.
static bool classofKind(Kind K)
static bool classof(const Decl *D)
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the associated-constraints of this template parameter.
void setDeclaredWithTypename(bool withTypename)
Set whether this template type parameter was declared with the 'typename' or 'class' keyword.
bool isPackExpansion() const
Whether this parameter pack is a pack expansion.
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition: Decl.h:3556
Declaration of an alias template.
static bool classof(const Decl *D)
CommonBase * newCommon(ASTContext &C) const override
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty alias template node.
TypeAliasTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
const TypeAliasTemplateDecl * getPreviousDecl() const
TypeAliasTemplateDecl * getInstantiatedFromMemberTemplate() const
const TypeAliasTemplateDecl * getCanonicalDecl() const
static bool classofKind(Kind K)
TypeAliasTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
TypeAliasDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:231
Represents a declaration of a type.
Definition: Decl.h:3391
const Type * getTypeForDecl() const
Definition: Decl.h:3415
A container of type source information.
Definition: Type.h:7326
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7337
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2754
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8119
A set of unresolved declarations.
Definition: UnresolvedSet.h:61
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2257
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
Definition: Decl.cpp:2756
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarDecl * getTemplatedDecl() const
Get the underlying variable declarations of the template.
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
spec_iterator spec_begin() const
Common * getCommonPtr() const
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
static bool classof(const Decl *D)
const VarTemplateDecl * getPreviousDecl() const
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
VarTemplateDecl * getInstantiatedFromMemberTemplate() const
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
const VarTemplateDecl * getCanonicalDecl() const
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
llvm::iterator_range< spec_iterator > spec_range
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
static bool classofKind(Kind K)
const VarTemplateDecl * getMostRecentDecl() const
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
spec_iterator spec_end() const
VarTemplateDecl * getMostRecentDecl()
spec_range specializations() const
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Get the template arguments as written.
void setMemberSpecialization()
Note that this member template is a specialization.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization()
Determines whether this variable template partial specialization was a specialization of a member par...
void Profile(llvm::FoldingSetNodeID &ID) const
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
All associated constraints of this partial specialization, including the requires clause and any cons...
void setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec)
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
VarTemplatePartialSpecializationDecl * getMostRecentDecl()
Represents a variable template specialization, which refers to a variable template with a given set o...
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
void setExternLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void setSpecializationKind(TemplateSpecializationKind TSK)
static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef< TemplateArgument > TemplateArgs, const ASTContext &Context)
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
const TemplateArgumentList & getTemplateInstantiationArgs() const
Retrieve the set of template arguments that should be used to instantiate the initializer of the vari...
SourceLocation getExternLoc() const
Gets the location of the extern keyword, if present.
static bool classof(const Decl *D)
void setTypeAsWritten(TypeSourceInfo *T)
Sets the type of this specialization as it was written by the user.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs)
Note that this variable template specialization is actually an instantiation of the given variable te...
void Profile(llvm::FoldingSetNodeID &ID) const
void setPointOfInstantiation(SourceLocation Loc)
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
void setInstantiationOf(VarTemplateDecl *TemplDecl)
Note that this variable template specialization is an instantiation of the given variable template.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
bool isExplicitInstantiationOrSpecialization() const
True if this declaration is an explicit specialization, explicit instantiation declaration,...
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this variable template specialization is an instantiation of a template (rather than an explicit s...
const ASTTemplateArgumentListInfo * getTemplateArgsInfo() const
TypeSourceInfo * getTypeAsWritten() const
Gets the type of this specialization as it was written by the user, if it was so written.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
VarTemplateSpecializationDecl * getMostRecentDecl()
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
@ Create
'copyin' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Definition: Specifiers.h:209
Decl * getPrimaryMergedDecl(Decl *D)
Get the primary declaration for a declaration from an AST file.
Definition: Decl.cpp:77
NamedDecl * getAsNamedDecl(TemplateParameter P)
StorageClass
Storage classes.
Definition: Specifiers.h:245
void * allocateDefaultArgStorageChain(const ASTContext &C)
TemplateDecl * getAsTypeTemplateDecl(Decl *D)
TemplateParameterList * getReplacedTemplateParameterList(Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
TagTypeKind
The kind of a tag type.
Definition: Type.h:6295
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition: Builtins.h:302
llvm::PointerUnion< TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, TemplateTemplateParmDecl * > TemplateParameter
Stores a template parameter of any kind.
Definition: DeclTemplate.h:65
std::optional< unsigned > getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
const FunctionProtoType * T
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition: Specifiers.h:185
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:195
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:188
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
bool isTemplateExplicitInstantiationOrSpecialization(TemplateSpecializationKind Kind)
True if this template specialization kind is an explicit specialization, explicit instantiation decla...
Definition: Specifiers.h:216
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
Definition: Format.h:5394
#define true
Definition: stdbool.h:21
#define false
Definition: stdbool.h:22
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
Data that is common to all of the declarations of a given class template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > PartialSpecializations
The class template partial specializations for this class template.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > Specializations
The class template specializations for this class template, including explicit specializations and in...
QualType InjectedClassNameType
The injected-class-name type for this class template.
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition: DeclBase.h:102
Data that is common to all of the declarations of a given function template.
Definition: DeclTemplate.h:964
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Definition: DeclTemplate.h:967
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
llvm::PointerIntPair< RedeclarableTemplateDecl *, 1, bool > InstantiatedFromMember
The template from which this was most directly instantiated (or null).
Definition: DeclTemplate.h:793
GlobalDeclID * LazySpecializations
If non-null, points to an array of specializations (including partial specializations) known only by ...
Definition: DeclTemplate.h:800
TemplateArgument * InjectedArgs
The set of "injected" template arguments used within this template.
Definition: DeclTemplate.h:809
static ArrayRef< TemplateArgument > getTemplateArgs(FunctionTemplateSpecializationInfo *I)
Definition: DeclTemplate.h:952
static DeclType * getDecl(FunctionTemplateSpecializationInfo *I)
Definition: DeclTemplate.h:947
static ArrayRef< TemplateArgument > getTemplateArgs(EntryType *D)
Definition: DeclTemplate.h:741
static DeclType * getDecl(EntryType *D)
Definition: DeclTemplate.h:737
SpecIterator(typename llvm::FoldingSetVector< EntryType >::iterator SetIter)
Definition: DeclTemplate.h:756
Data that is common to all of the declarations of a given variable template.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > PartialSpecializations
The variable template partial specializations for this variable template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > Specializations
The variable template specializations for this variable template, including explicit specializations ...