1e5dd7070Spatrick //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements the C++ related Decl classes for templates.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
14e5dd7070Spatrick #include "clang/AST/ASTContext.h"
15e5dd7070Spatrick #include "clang/AST/ASTMutationListener.h"
16e5dd7070Spatrick #include "clang/AST/DeclCXX.h"
17e5dd7070Spatrick #include "clang/AST/DeclarationName.h"
18e5dd7070Spatrick #include "clang/AST/Expr.h"
19e5dd7070Spatrick #include "clang/AST/ExternalASTSource.h"
20e5dd7070Spatrick #include "clang/AST/TemplateBase.h"
21e5dd7070Spatrick #include "clang/AST/TemplateName.h"
22e5dd7070Spatrick #include "clang/AST/Type.h"
23e5dd7070Spatrick #include "clang/AST/TypeLoc.h"
24e5dd7070Spatrick #include "clang/Basic/Builtins.h"
25e5dd7070Spatrick #include "clang/Basic/LLVM.h"
26e5dd7070Spatrick #include "clang/Basic/SourceLocation.h"
27e5dd7070Spatrick #include "llvm/ADT/ArrayRef.h"
28e5dd7070Spatrick #include "llvm/ADT/FoldingSet.h"
29e5dd7070Spatrick #include "llvm/ADT/PointerUnion.h"
30*12c85518Srobert #include "llvm/ADT/STLExtras.h"
31e5dd7070Spatrick #include "llvm/ADT/SmallVector.h"
32e5dd7070Spatrick #include "llvm/Support/Casting.h"
33e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
34e5dd7070Spatrick #include <algorithm>
35e5dd7070Spatrick #include <cassert>
36e5dd7070Spatrick #include <cstdint>
37e5dd7070Spatrick #include <memory>
38*12c85518Srobert #include <optional>
39e5dd7070Spatrick #include <utility>
40e5dd7070Spatrick
41e5dd7070Spatrick using namespace clang;
42e5dd7070Spatrick
43e5dd7070Spatrick //===----------------------------------------------------------------------===//
44e5dd7070Spatrick // TemplateParameterList Implementation
45e5dd7070Spatrick //===----------------------------------------------------------------------===//
46e5dd7070Spatrick
47e5dd7070Spatrick
TemplateParameterList(const ASTContext & C,SourceLocation TemplateLoc,SourceLocation LAngleLoc,ArrayRef<NamedDecl * > Params,SourceLocation RAngleLoc,Expr * RequiresClause)48e5dd7070Spatrick TemplateParameterList::TemplateParameterList(const ASTContext& C,
49e5dd7070Spatrick SourceLocation TemplateLoc,
50e5dd7070Spatrick SourceLocation LAngleLoc,
51e5dd7070Spatrick ArrayRef<NamedDecl *> Params,
52e5dd7070Spatrick SourceLocation RAngleLoc,
53e5dd7070Spatrick Expr *RequiresClause)
54e5dd7070Spatrick : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
55e5dd7070Spatrick NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
56e5dd7070Spatrick HasRequiresClause(RequiresClause != nullptr),
57e5dd7070Spatrick HasConstrainedParameters(false) {
58e5dd7070Spatrick for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
59e5dd7070Spatrick NamedDecl *P = Params[Idx];
60e5dd7070Spatrick begin()[Idx] = P;
61e5dd7070Spatrick
62e5dd7070Spatrick bool IsPack = P->isTemplateParameterPack();
63e5dd7070Spatrick if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
64e5dd7070Spatrick if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
65e5dd7070Spatrick ContainsUnexpandedParameterPack = true;
66e5dd7070Spatrick if (NTTP->hasPlaceholderTypeConstraint())
67e5dd7070Spatrick HasConstrainedParameters = true;
68e5dd7070Spatrick } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
69e5dd7070Spatrick if (!IsPack &&
70e5dd7070Spatrick TTP->getTemplateParameters()->containsUnexpandedParameterPack())
71e5dd7070Spatrick ContainsUnexpandedParameterPack = true;
72a9ac8606Spatrick } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
73a9ac8606Spatrick if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
74e5dd7070Spatrick if (TC->getImmediatelyDeclaredConstraint()
75e5dd7070Spatrick ->containsUnexpandedParameterPack())
76e5dd7070Spatrick ContainsUnexpandedParameterPack = true;
77a9ac8606Spatrick }
78a9ac8606Spatrick if (TTP->hasTypeConstraint())
79e5dd7070Spatrick HasConstrainedParameters = true;
80a9ac8606Spatrick } else {
81*12c85518Srobert llvm_unreachable("unexpected template parameter type");
82e5dd7070Spatrick }
83e5dd7070Spatrick // FIXME: If a default argument contains an unexpanded parameter pack, the
84e5dd7070Spatrick // template parameter list does too.
85e5dd7070Spatrick }
86e5dd7070Spatrick
87e5dd7070Spatrick if (HasRequiresClause) {
88e5dd7070Spatrick if (RequiresClause->containsUnexpandedParameterPack())
89e5dd7070Spatrick ContainsUnexpandedParameterPack = true;
90e5dd7070Spatrick *getTrailingObjects<Expr *>() = RequiresClause;
91e5dd7070Spatrick }
92e5dd7070Spatrick }
93e5dd7070Spatrick
containsUnexpandedParameterPack() const94a9ac8606Spatrick bool TemplateParameterList::containsUnexpandedParameterPack() const {
95a9ac8606Spatrick if (ContainsUnexpandedParameterPack)
96a9ac8606Spatrick return true;
97a9ac8606Spatrick if (!HasConstrainedParameters)
98a9ac8606Spatrick return false;
99a9ac8606Spatrick
100a9ac8606Spatrick // An implicit constrained parameter might have had a use of an unexpanded
101a9ac8606Spatrick // pack added to it after the template parameter list was created. All
102a9ac8606Spatrick // implicit parameters are at the end of the parameter list.
103a9ac8606Spatrick for (const NamedDecl *Param : llvm::reverse(asArray())) {
104a9ac8606Spatrick if (!Param->isImplicit())
105a9ac8606Spatrick break;
106a9ac8606Spatrick
107a9ac8606Spatrick if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
108a9ac8606Spatrick const auto *TC = TTP->getTypeConstraint();
109a9ac8606Spatrick if (TC && TC->getImmediatelyDeclaredConstraint()
110a9ac8606Spatrick ->containsUnexpandedParameterPack())
111a9ac8606Spatrick return true;
112a9ac8606Spatrick }
113a9ac8606Spatrick }
114a9ac8606Spatrick
115a9ac8606Spatrick return false;
116a9ac8606Spatrick }
117a9ac8606Spatrick
118e5dd7070Spatrick TemplateParameterList *
Create(const ASTContext & C,SourceLocation TemplateLoc,SourceLocation LAngleLoc,ArrayRef<NamedDecl * > Params,SourceLocation RAngleLoc,Expr * RequiresClause)119e5dd7070Spatrick TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
120e5dd7070Spatrick SourceLocation LAngleLoc,
121e5dd7070Spatrick ArrayRef<NamedDecl *> Params,
122e5dd7070Spatrick SourceLocation RAngleLoc, Expr *RequiresClause) {
123e5dd7070Spatrick void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
124e5dd7070Spatrick Params.size(), RequiresClause ? 1u : 0u),
125e5dd7070Spatrick alignof(TemplateParameterList));
126e5dd7070Spatrick return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
127e5dd7070Spatrick RAngleLoc, RequiresClause);
128e5dd7070Spatrick }
129e5dd7070Spatrick
getMinRequiredArguments() const130e5dd7070Spatrick unsigned TemplateParameterList::getMinRequiredArguments() const {
131e5dd7070Spatrick unsigned NumRequiredArgs = 0;
132e5dd7070Spatrick for (const NamedDecl *P : asArray()) {
133e5dd7070Spatrick if (P->isTemplateParameterPack()) {
134*12c85518Srobert if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
135a9ac8606Spatrick NumRequiredArgs += *Expansions;
136e5dd7070Spatrick continue;
137e5dd7070Spatrick }
138e5dd7070Spatrick break;
139e5dd7070Spatrick }
140e5dd7070Spatrick
141e5dd7070Spatrick if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
142e5dd7070Spatrick if (TTP->hasDefaultArgument())
143e5dd7070Spatrick break;
144e5dd7070Spatrick } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
145e5dd7070Spatrick if (NTTP->hasDefaultArgument())
146e5dd7070Spatrick break;
147e5dd7070Spatrick } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
148e5dd7070Spatrick break;
149e5dd7070Spatrick
150e5dd7070Spatrick ++NumRequiredArgs;
151e5dd7070Spatrick }
152e5dd7070Spatrick
153e5dd7070Spatrick return NumRequiredArgs;
154e5dd7070Spatrick }
155e5dd7070Spatrick
getDepth() const156e5dd7070Spatrick unsigned TemplateParameterList::getDepth() const {
157e5dd7070Spatrick if (size() == 0)
158e5dd7070Spatrick return 0;
159e5dd7070Spatrick
160e5dd7070Spatrick const NamedDecl *FirstParm = getParam(0);
161e5dd7070Spatrick if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
162e5dd7070Spatrick return TTP->getDepth();
163e5dd7070Spatrick else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
164e5dd7070Spatrick return NTTP->getDepth();
165e5dd7070Spatrick else
166e5dd7070Spatrick return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
167e5dd7070Spatrick }
168e5dd7070Spatrick
AdoptTemplateParameterList(TemplateParameterList * Params,DeclContext * Owner)169*12c85518Srobert static bool AdoptTemplateParameterList(TemplateParameterList *Params,
170e5dd7070Spatrick DeclContext *Owner) {
171*12c85518Srobert bool Invalid = false;
172e5dd7070Spatrick for (NamedDecl *P : *Params) {
173e5dd7070Spatrick P->setDeclContext(Owner);
174e5dd7070Spatrick
175e5dd7070Spatrick if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
176*12c85518Srobert if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
177*12c85518Srobert Invalid = true;
178*12c85518Srobert
179*12c85518Srobert if (P->isInvalidDecl())
180*12c85518Srobert Invalid = true;
181e5dd7070Spatrick }
182*12c85518Srobert return Invalid;
183e5dd7070Spatrick }
184e5dd7070Spatrick
185e5dd7070Spatrick void TemplateParameterList::
getAssociatedConstraints(llvm::SmallVectorImpl<const Expr * > & AC) const186e5dd7070Spatrick getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
187e5dd7070Spatrick if (HasConstrainedParameters)
188e5dd7070Spatrick for (const NamedDecl *Param : *this) {
189e5dd7070Spatrick if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
190e5dd7070Spatrick if (const auto *TC = TTP->getTypeConstraint())
191e5dd7070Spatrick AC.push_back(TC->getImmediatelyDeclaredConstraint());
192e5dd7070Spatrick } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
193e5dd7070Spatrick if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
194e5dd7070Spatrick AC.push_back(E);
195e5dd7070Spatrick }
196e5dd7070Spatrick }
197e5dd7070Spatrick if (HasRequiresClause)
198e5dd7070Spatrick AC.push_back(getRequiresClause());
199e5dd7070Spatrick }
200e5dd7070Spatrick
hasAssociatedConstraints() const201e5dd7070Spatrick bool TemplateParameterList::hasAssociatedConstraints() const {
202e5dd7070Spatrick return HasRequiresClause || HasConstrainedParameters;
203e5dd7070Spatrick }
204e5dd7070Spatrick
shouldIncludeTypeForArgument(const PrintingPolicy & Policy,const TemplateParameterList * TPL,unsigned Idx)205a9ac8606Spatrick bool TemplateParameterList::shouldIncludeTypeForArgument(
206*12c85518Srobert const PrintingPolicy &Policy, const TemplateParameterList *TPL,
207*12c85518Srobert unsigned Idx) {
208*12c85518Srobert if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
209a9ac8606Spatrick return true;
210a9ac8606Spatrick const NamedDecl *TemplParam = TPL->getParam(Idx);
211a9ac8606Spatrick if (const auto *ParamValueDecl =
212a9ac8606Spatrick dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
213a9ac8606Spatrick if (ParamValueDecl->getType()->getContainedDeducedType())
214a9ac8606Spatrick return true;
215a9ac8606Spatrick return false;
216a9ac8606Spatrick }
217a9ac8606Spatrick
218e5dd7070Spatrick namespace clang {
219e5dd7070Spatrick
allocateDefaultArgStorageChain(const ASTContext & C)220e5dd7070Spatrick void *allocateDefaultArgStorageChain(const ASTContext &C) {
221e5dd7070Spatrick return new (C) char[sizeof(void*) * 2];
222e5dd7070Spatrick }
223e5dd7070Spatrick
224e5dd7070Spatrick } // namespace clang
225e5dd7070Spatrick
226e5dd7070Spatrick //===----------------------------------------------------------------------===//
227e5dd7070Spatrick // TemplateDecl Implementation
228e5dd7070Spatrick //===----------------------------------------------------------------------===//
229e5dd7070Spatrick
TemplateDecl(Kind DK,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)230e5dd7070Spatrick TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
231e5dd7070Spatrick DeclarationName Name, TemplateParameterList *Params,
232e5dd7070Spatrick NamedDecl *Decl)
233e5dd7070Spatrick : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
234e5dd7070Spatrick
anchor()235e5dd7070Spatrick void TemplateDecl::anchor() {}
236e5dd7070Spatrick
237e5dd7070Spatrick void TemplateDecl::
getAssociatedConstraints(llvm::SmallVectorImpl<const Expr * > & AC) const238e5dd7070Spatrick getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
239e5dd7070Spatrick TemplateParams->getAssociatedConstraints(AC);
240e5dd7070Spatrick if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
241e5dd7070Spatrick if (const Expr *TRC = FD->getTrailingRequiresClause())
242e5dd7070Spatrick AC.push_back(TRC);
243e5dd7070Spatrick }
244e5dd7070Spatrick
hasAssociatedConstraints() const245e5dd7070Spatrick bool TemplateDecl::hasAssociatedConstraints() const {
246e5dd7070Spatrick if (TemplateParams->hasAssociatedConstraints())
247e5dd7070Spatrick return true;
248e5dd7070Spatrick if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
249e5dd7070Spatrick return FD->getTrailingRequiresClause();
250e5dd7070Spatrick return false;
251e5dd7070Spatrick }
252e5dd7070Spatrick
isTypeAlias() const253*12c85518Srobert bool TemplateDecl::isTypeAlias() const {
254*12c85518Srobert switch (getKind()) {
255*12c85518Srobert case TemplateDecl::TypeAliasTemplate:
256*12c85518Srobert case TemplateDecl::BuiltinTemplate:
257*12c85518Srobert return true;
258*12c85518Srobert default:
259*12c85518Srobert return false;
260*12c85518Srobert };
261*12c85518Srobert }
262*12c85518Srobert
263e5dd7070Spatrick //===----------------------------------------------------------------------===//
264e5dd7070Spatrick // RedeclarableTemplateDecl Implementation
265e5dd7070Spatrick //===----------------------------------------------------------------------===//
266e5dd7070Spatrick
anchor()267e5dd7070Spatrick void RedeclarableTemplateDecl::anchor() {}
268e5dd7070Spatrick
getCommonPtr() const269e5dd7070Spatrick RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
270e5dd7070Spatrick if (Common)
271e5dd7070Spatrick return Common;
272e5dd7070Spatrick
273e5dd7070Spatrick // Walk the previous-declaration chain until we either find a declaration
274e5dd7070Spatrick // with a common pointer or we run out of previous declarations.
275e5dd7070Spatrick SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
276e5dd7070Spatrick for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
277e5dd7070Spatrick Prev = Prev->getPreviousDecl()) {
278e5dd7070Spatrick if (Prev->Common) {
279e5dd7070Spatrick Common = Prev->Common;
280e5dd7070Spatrick break;
281e5dd7070Spatrick }
282e5dd7070Spatrick
283e5dd7070Spatrick PrevDecls.push_back(Prev);
284e5dd7070Spatrick }
285e5dd7070Spatrick
286e5dd7070Spatrick // If we never found a common pointer, allocate one now.
287e5dd7070Spatrick if (!Common) {
288e5dd7070Spatrick // FIXME: If any of the declarations is from an AST file, we probably
289e5dd7070Spatrick // need an update record to add the common data.
290e5dd7070Spatrick
291e5dd7070Spatrick Common = newCommon(getASTContext());
292e5dd7070Spatrick }
293e5dd7070Spatrick
294e5dd7070Spatrick // Update any previous declarations we saw with the common pointer.
295e5dd7070Spatrick for (const RedeclarableTemplateDecl *Prev : PrevDecls)
296e5dd7070Spatrick Prev->Common = Common;
297e5dd7070Spatrick
298e5dd7070Spatrick return Common;
299e5dd7070Spatrick }
300e5dd7070Spatrick
loadLazySpecializationsImpl() const301e5dd7070Spatrick void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
302e5dd7070Spatrick // Grab the most recent declaration to ensure we've loaded any lazy
303e5dd7070Spatrick // redeclarations of this template.
304e5dd7070Spatrick CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
305e5dd7070Spatrick if (CommonBasePtr->LazySpecializations) {
306e5dd7070Spatrick ASTContext &Context = getASTContext();
307e5dd7070Spatrick uint32_t *Specs = CommonBasePtr->LazySpecializations;
308e5dd7070Spatrick CommonBasePtr->LazySpecializations = nullptr;
309e5dd7070Spatrick for (uint32_t I = 0, N = *Specs++; I != N; ++I)
310e5dd7070Spatrick (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
311e5dd7070Spatrick }
312e5dd7070Spatrick }
313e5dd7070Spatrick
314e5dd7070Spatrick template<class EntryType, typename... ProfileArguments>
315e5dd7070Spatrick typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
findSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specs,void * & InsertPos,ProfileArguments &&...ProfileArgs)316e5dd7070Spatrick RedeclarableTemplateDecl::findSpecializationImpl(
317e5dd7070Spatrick llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
318e5dd7070Spatrick ProfileArguments&&... ProfileArgs) {
319e5dd7070Spatrick using SETraits = SpecEntryTraits<EntryType>;
320e5dd7070Spatrick
321e5dd7070Spatrick llvm::FoldingSetNodeID ID;
322e5dd7070Spatrick EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
323e5dd7070Spatrick getASTContext());
324e5dd7070Spatrick EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
325e5dd7070Spatrick return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
326e5dd7070Spatrick }
327e5dd7070Spatrick
328e5dd7070Spatrick template<class Derived, class EntryType>
addSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specializations,EntryType * Entry,void * InsertPos)329e5dd7070Spatrick void RedeclarableTemplateDecl::addSpecializationImpl(
330e5dd7070Spatrick llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
331e5dd7070Spatrick void *InsertPos) {
332e5dd7070Spatrick using SETraits = SpecEntryTraits<EntryType>;
333e5dd7070Spatrick
334e5dd7070Spatrick if (InsertPos) {
335e5dd7070Spatrick #ifndef NDEBUG
336e5dd7070Spatrick void *CorrectInsertPos;
337e5dd7070Spatrick assert(!findSpecializationImpl(Specializations,
338e5dd7070Spatrick CorrectInsertPos,
339e5dd7070Spatrick SETraits::getTemplateArgs(Entry)) &&
340e5dd7070Spatrick InsertPos == CorrectInsertPos &&
341e5dd7070Spatrick "given incorrect InsertPos for specialization");
342e5dd7070Spatrick #endif
343e5dd7070Spatrick Specializations.InsertNode(Entry, InsertPos);
344e5dd7070Spatrick } else {
345e5dd7070Spatrick EntryType *Existing = Specializations.GetOrInsertNode(Entry);
346e5dd7070Spatrick (void)Existing;
347e5dd7070Spatrick assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
348e5dd7070Spatrick "non-canonical specialization?");
349e5dd7070Spatrick }
350e5dd7070Spatrick
351e5dd7070Spatrick if (ASTMutationListener *L = getASTMutationListener())
352e5dd7070Spatrick L->AddedCXXTemplateSpecialization(cast<Derived>(this),
353e5dd7070Spatrick SETraits::getDecl(Entry));
354e5dd7070Spatrick }
355e5dd7070Spatrick
getInjectedTemplateArgs()356*12c85518Srobert ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
357*12c85518Srobert TemplateParameterList *Params = getTemplateParameters();
358*12c85518Srobert auto *CommonPtr = getCommonPtr();
359*12c85518Srobert if (!CommonPtr->InjectedArgs) {
360*12c85518Srobert auto &Context = getASTContext();
361*12c85518Srobert SmallVector<TemplateArgument, 16> TemplateArgs;
362*12c85518Srobert Context.getInjectedTemplateArgs(Params, TemplateArgs);
363*12c85518Srobert CommonPtr->InjectedArgs =
364*12c85518Srobert new (Context) TemplateArgument[TemplateArgs.size()];
365*12c85518Srobert std::copy(TemplateArgs.begin(), TemplateArgs.end(),
366*12c85518Srobert CommonPtr->InjectedArgs);
367*12c85518Srobert }
368*12c85518Srobert
369*12c85518Srobert return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
370*12c85518Srobert }
371*12c85518Srobert
372e5dd7070Spatrick //===----------------------------------------------------------------------===//
373e5dd7070Spatrick // FunctionTemplateDecl Implementation
374e5dd7070Spatrick //===----------------------------------------------------------------------===//
375e5dd7070Spatrick
376*12c85518Srobert FunctionTemplateDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)377*12c85518Srobert FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
378e5dd7070Spatrick DeclarationName Name,
379*12c85518Srobert TemplateParameterList *Params, NamedDecl *Decl) {
380*12c85518Srobert bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
381*12c85518Srobert auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
382*12c85518Srobert if (Invalid)
383*12c85518Srobert TD->setInvalidDecl();
384*12c85518Srobert return TD;
385e5dd7070Spatrick }
386e5dd7070Spatrick
CreateDeserialized(ASTContext & C,unsigned ID)387e5dd7070Spatrick FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
388e5dd7070Spatrick unsigned ID) {
389e5dd7070Spatrick return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
390e5dd7070Spatrick DeclarationName(), nullptr, nullptr);
391e5dd7070Spatrick }
392e5dd7070Spatrick
393e5dd7070Spatrick RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const394e5dd7070Spatrick FunctionTemplateDecl::newCommon(ASTContext &C) const {
395e5dd7070Spatrick auto *CommonPtr = new (C) Common;
396e5dd7070Spatrick C.addDestruction(CommonPtr);
397e5dd7070Spatrick return CommonPtr;
398e5dd7070Spatrick }
399e5dd7070Spatrick
LoadLazySpecializations() const400e5dd7070Spatrick void FunctionTemplateDecl::LoadLazySpecializations() const {
401e5dd7070Spatrick loadLazySpecializationsImpl();
402e5dd7070Spatrick }
403e5dd7070Spatrick
404e5dd7070Spatrick llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
getSpecializations() const405e5dd7070Spatrick FunctionTemplateDecl::getSpecializations() const {
406e5dd7070Spatrick LoadLazySpecializations();
407e5dd7070Spatrick return getCommonPtr()->Specializations;
408e5dd7070Spatrick }
409e5dd7070Spatrick
410e5dd7070Spatrick FunctionDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)411e5dd7070Spatrick FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
412e5dd7070Spatrick void *&InsertPos) {
413e5dd7070Spatrick return findSpecializationImpl(getSpecializations(), InsertPos, Args);
414e5dd7070Spatrick }
415e5dd7070Spatrick
addSpecialization(FunctionTemplateSpecializationInfo * Info,void * InsertPos)416e5dd7070Spatrick void FunctionTemplateDecl::addSpecialization(
417e5dd7070Spatrick FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
418e5dd7070Spatrick addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
419e5dd7070Spatrick InsertPos);
420e5dd7070Spatrick }
421e5dd7070Spatrick
mergePrevDecl(FunctionTemplateDecl * Prev)422e5dd7070Spatrick void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
423e5dd7070Spatrick using Base = RedeclarableTemplateDecl;
424e5dd7070Spatrick
425e5dd7070Spatrick // If we haven't created a common pointer yet, then it can just be created
426e5dd7070Spatrick // with the usual method.
427e5dd7070Spatrick if (!Base::Common)
428e5dd7070Spatrick return;
429e5dd7070Spatrick
430e5dd7070Spatrick Common *ThisCommon = static_cast<Common *>(Base::Common);
431e5dd7070Spatrick Common *PrevCommon = nullptr;
432e5dd7070Spatrick SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
433e5dd7070Spatrick for (; Prev; Prev = Prev->getPreviousDecl()) {
434e5dd7070Spatrick if (Prev->Base::Common) {
435e5dd7070Spatrick PrevCommon = static_cast<Common *>(Prev->Base::Common);
436e5dd7070Spatrick break;
437e5dd7070Spatrick }
438e5dd7070Spatrick PreviousDecls.push_back(Prev);
439e5dd7070Spatrick }
440e5dd7070Spatrick
441e5dd7070Spatrick // If the previous redecl chain hasn't created a common pointer yet, then just
442e5dd7070Spatrick // use this common pointer.
443e5dd7070Spatrick if (!PrevCommon) {
444e5dd7070Spatrick for (auto *D : PreviousDecls)
445e5dd7070Spatrick D->Base::Common = ThisCommon;
446e5dd7070Spatrick return;
447e5dd7070Spatrick }
448e5dd7070Spatrick
449e5dd7070Spatrick // Ensure we don't leak any important state.
450e5dd7070Spatrick assert(ThisCommon->Specializations.size() == 0 &&
451e5dd7070Spatrick "Can't merge incompatible declarations!");
452e5dd7070Spatrick
453e5dd7070Spatrick Base::Common = PrevCommon;
454e5dd7070Spatrick }
455e5dd7070Spatrick
456e5dd7070Spatrick //===----------------------------------------------------------------------===//
457e5dd7070Spatrick // ClassTemplateDecl Implementation
458e5dd7070Spatrick //===----------------------------------------------------------------------===//
459e5dd7070Spatrick
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)460*12c85518Srobert ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
461e5dd7070Spatrick SourceLocation L,
462e5dd7070Spatrick DeclarationName Name,
463e5dd7070Spatrick TemplateParameterList *Params,
464e5dd7070Spatrick NamedDecl *Decl) {
465*12c85518Srobert bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
466*12c85518Srobert auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
467*12c85518Srobert if (Invalid)
468*12c85518Srobert TD->setInvalidDecl();
469*12c85518Srobert return TD;
470e5dd7070Spatrick }
471e5dd7070Spatrick
CreateDeserialized(ASTContext & C,unsigned ID)472e5dd7070Spatrick ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
473e5dd7070Spatrick unsigned ID) {
474e5dd7070Spatrick return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
475e5dd7070Spatrick DeclarationName(), nullptr, nullptr);
476e5dd7070Spatrick }
477e5dd7070Spatrick
LoadLazySpecializations() const478e5dd7070Spatrick void ClassTemplateDecl::LoadLazySpecializations() const {
479e5dd7070Spatrick loadLazySpecializationsImpl();
480e5dd7070Spatrick }
481e5dd7070Spatrick
482e5dd7070Spatrick llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
getSpecializations() const483e5dd7070Spatrick ClassTemplateDecl::getSpecializations() const {
484e5dd7070Spatrick LoadLazySpecializations();
485e5dd7070Spatrick return getCommonPtr()->Specializations;
486e5dd7070Spatrick }
487e5dd7070Spatrick
488e5dd7070Spatrick llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations() const489a9ac8606Spatrick ClassTemplateDecl::getPartialSpecializations() const {
490e5dd7070Spatrick LoadLazySpecializations();
491e5dd7070Spatrick return getCommonPtr()->PartialSpecializations;
492e5dd7070Spatrick }
493e5dd7070Spatrick
494e5dd7070Spatrick RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const495e5dd7070Spatrick ClassTemplateDecl::newCommon(ASTContext &C) const {
496e5dd7070Spatrick auto *CommonPtr = new (C) Common;
497e5dd7070Spatrick C.addDestruction(CommonPtr);
498e5dd7070Spatrick return CommonPtr;
499e5dd7070Spatrick }
500e5dd7070Spatrick
501e5dd7070Spatrick ClassTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)502e5dd7070Spatrick ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
503e5dd7070Spatrick void *&InsertPos) {
504e5dd7070Spatrick return findSpecializationImpl(getSpecializations(), InsertPos, Args);
505e5dd7070Spatrick }
506e5dd7070Spatrick
AddSpecialization(ClassTemplateSpecializationDecl * D,void * InsertPos)507e5dd7070Spatrick void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
508e5dd7070Spatrick void *InsertPos) {
509e5dd7070Spatrick addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
510e5dd7070Spatrick }
511e5dd7070Spatrick
512e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,TemplateParameterList * TPL,void * & InsertPos)513e5dd7070Spatrick ClassTemplateDecl::findPartialSpecialization(
514e5dd7070Spatrick ArrayRef<TemplateArgument> Args,
515e5dd7070Spatrick TemplateParameterList *TPL, void *&InsertPos) {
516e5dd7070Spatrick return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
517e5dd7070Spatrick TPL);
518e5dd7070Spatrick }
519e5dd7070Spatrick
ProfileTemplateParameterList(ASTContext & C,llvm::FoldingSetNodeID & ID,const TemplateParameterList * TPL)520e5dd7070Spatrick static void ProfileTemplateParameterList(ASTContext &C,
521e5dd7070Spatrick llvm::FoldingSetNodeID &ID, const TemplateParameterList *TPL) {
522e5dd7070Spatrick const Expr *RC = TPL->getRequiresClause();
523e5dd7070Spatrick ID.AddBoolean(RC != nullptr);
524e5dd7070Spatrick if (RC)
525e5dd7070Spatrick RC->Profile(ID, C, /*Canonical=*/true);
526e5dd7070Spatrick ID.AddInteger(TPL->size());
527e5dd7070Spatrick for (NamedDecl *D : *TPL) {
528e5dd7070Spatrick if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
529e5dd7070Spatrick ID.AddInteger(0);
530e5dd7070Spatrick ID.AddBoolean(NTTP->isParameterPack());
531e5dd7070Spatrick NTTP->getType().getCanonicalType().Profile(ID);
532*12c85518Srobert ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
533*12c85518Srobert if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
534*12c85518Srobert E->Profile(ID, C, /*Canonical=*/true);
535e5dd7070Spatrick continue;
536e5dd7070Spatrick }
537e5dd7070Spatrick if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
538e5dd7070Spatrick ID.AddInteger(1);
539e5dd7070Spatrick ID.AddBoolean(TTP->isParameterPack());
540e5dd7070Spatrick ID.AddBoolean(TTP->hasTypeConstraint());
541e5dd7070Spatrick if (const TypeConstraint *TC = TTP->getTypeConstraint())
542e5dd7070Spatrick TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
543e5dd7070Spatrick /*Canonical=*/true);
544e5dd7070Spatrick continue;
545e5dd7070Spatrick }
546e5dd7070Spatrick const auto *TTP = cast<TemplateTemplateParmDecl>(D);
547e5dd7070Spatrick ID.AddInteger(2);
548e5dd7070Spatrick ID.AddBoolean(TTP->isParameterPack());
549e5dd7070Spatrick ProfileTemplateParameterList(C, ID, TTP->getTemplateParameters());
550e5dd7070Spatrick }
551e5dd7070Spatrick }
552e5dd7070Spatrick
553e5dd7070Spatrick void
Profile(llvm::FoldingSetNodeID & ID,ArrayRef<TemplateArgument> TemplateArgs,TemplateParameterList * TPL,ASTContext & Context)554e5dd7070Spatrick ClassTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
555e5dd7070Spatrick ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
556e5dd7070Spatrick ASTContext &Context) {
557e5dd7070Spatrick ID.AddInteger(TemplateArgs.size());
558e5dd7070Spatrick for (const TemplateArgument &TemplateArg : TemplateArgs)
559e5dd7070Spatrick TemplateArg.Profile(ID, Context);
560e5dd7070Spatrick ProfileTemplateParameterList(Context, ID, TPL);
561e5dd7070Spatrick }
562e5dd7070Spatrick
AddPartialSpecialization(ClassTemplatePartialSpecializationDecl * D,void * InsertPos)563e5dd7070Spatrick void ClassTemplateDecl::AddPartialSpecialization(
564e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *D,
565e5dd7070Spatrick void *InsertPos) {
566e5dd7070Spatrick if (InsertPos)
567e5dd7070Spatrick getPartialSpecializations().InsertNode(D, InsertPos);
568e5dd7070Spatrick else {
569e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *Existing
570e5dd7070Spatrick = getPartialSpecializations().GetOrInsertNode(D);
571e5dd7070Spatrick (void)Existing;
572e5dd7070Spatrick assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
573e5dd7070Spatrick }
574e5dd7070Spatrick
575e5dd7070Spatrick if (ASTMutationListener *L = getASTMutationListener())
576e5dd7070Spatrick L->AddedCXXTemplateSpecialization(this, D);
577e5dd7070Spatrick }
578e5dd7070Spatrick
getPartialSpecializations(SmallVectorImpl<ClassTemplatePartialSpecializationDecl * > & PS) const579e5dd7070Spatrick void ClassTemplateDecl::getPartialSpecializations(
580a9ac8606Spatrick SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {
581e5dd7070Spatrick llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
582e5dd7070Spatrick = getPartialSpecializations();
583e5dd7070Spatrick PS.clear();
584e5dd7070Spatrick PS.reserve(PartialSpecs.size());
585e5dd7070Spatrick for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
586e5dd7070Spatrick PS.push_back(P.getMostRecentDecl());
587e5dd7070Spatrick }
588e5dd7070Spatrick
589e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(QualType T)590e5dd7070Spatrick ClassTemplateDecl::findPartialSpecialization(QualType T) {
591e5dd7070Spatrick ASTContext &Context = getASTContext();
592e5dd7070Spatrick for (ClassTemplatePartialSpecializationDecl &P :
593e5dd7070Spatrick getPartialSpecializations()) {
594e5dd7070Spatrick if (Context.hasSameType(P.getInjectedSpecializationType(), T))
595e5dd7070Spatrick return P.getMostRecentDecl();
596e5dd7070Spatrick }
597e5dd7070Spatrick
598e5dd7070Spatrick return nullptr;
599e5dd7070Spatrick }
600e5dd7070Spatrick
601e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl * D)602e5dd7070Spatrick ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
603e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *D) {
604e5dd7070Spatrick Decl *DCanon = D->getCanonicalDecl();
605e5dd7070Spatrick for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
606e5dd7070Spatrick if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
607e5dd7070Spatrick return P.getMostRecentDecl();
608e5dd7070Spatrick }
609e5dd7070Spatrick
610e5dd7070Spatrick return nullptr;
611e5dd7070Spatrick }
612e5dd7070Spatrick
613e5dd7070Spatrick QualType
getInjectedClassNameSpecialization()614e5dd7070Spatrick ClassTemplateDecl::getInjectedClassNameSpecialization() {
615e5dd7070Spatrick Common *CommonPtr = getCommonPtr();
616e5dd7070Spatrick if (!CommonPtr->InjectedClassNameType.isNull())
617e5dd7070Spatrick return CommonPtr->InjectedClassNameType;
618e5dd7070Spatrick
619e5dd7070Spatrick // C++0x [temp.dep.type]p2:
620e5dd7070Spatrick // The template argument list of a primary template is a template argument
621e5dd7070Spatrick // list in which the nth template argument has the value of the nth template
622e5dd7070Spatrick // parameter of the class template. If the nth template parameter is a
623e5dd7070Spatrick // template parameter pack (14.5.3), the nth template argument is a pack
624e5dd7070Spatrick // expansion (14.5.3) whose pattern is the name of the template parameter
625e5dd7070Spatrick // pack.
626e5dd7070Spatrick ASTContext &Context = getASTContext();
627e5dd7070Spatrick TemplateParameterList *Params = getTemplateParameters();
628e5dd7070Spatrick SmallVector<TemplateArgument, 16> TemplateArgs;
629e5dd7070Spatrick Context.getInjectedTemplateArgs(Params, TemplateArgs);
630e5dd7070Spatrick CommonPtr->InjectedClassNameType
631e5dd7070Spatrick = Context.getTemplateSpecializationType(TemplateName(this),
632e5dd7070Spatrick TemplateArgs);
633e5dd7070Spatrick return CommonPtr->InjectedClassNameType;
634e5dd7070Spatrick }
635e5dd7070Spatrick
636e5dd7070Spatrick //===----------------------------------------------------------------------===//
637e5dd7070Spatrick // TemplateTypeParm Allocation/Deallocation Method Implementations
638e5dd7070Spatrick //===----------------------------------------------------------------------===//
639e5dd7070Spatrick
Create(const ASTContext & C,DeclContext * DC,SourceLocation KeyLoc,SourceLocation NameLoc,unsigned D,unsigned P,IdentifierInfo * Id,bool Typename,bool ParameterPack,bool HasTypeConstraint,std::optional<unsigned> NumExpanded)640*12c85518Srobert TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
641*12c85518Srobert const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
642*12c85518Srobert SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
643*12c85518Srobert bool Typename, bool ParameterPack, bool HasTypeConstraint,
644*12c85518Srobert std::optional<unsigned> NumExpanded) {
645e5dd7070Spatrick auto *TTPDecl =
646e5dd7070Spatrick new (C, DC,
647e5dd7070Spatrick additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
648e5dd7070Spatrick TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
649e5dd7070Spatrick HasTypeConstraint, NumExpanded);
650e5dd7070Spatrick QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
651e5dd7070Spatrick TTPDecl->setTypeForDecl(TTPType.getTypePtr());
652e5dd7070Spatrick return TTPDecl;
653e5dd7070Spatrick }
654e5dd7070Spatrick
655e5dd7070Spatrick TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,unsigned ID)656e5dd7070Spatrick TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
657*12c85518Srobert return new (C, ID)
658*12c85518Srobert TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
659*12c85518Srobert false, false, std::nullopt);
660e5dd7070Spatrick }
661e5dd7070Spatrick
662e5dd7070Spatrick TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,unsigned ID,bool HasTypeConstraint)663e5dd7070Spatrick TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID,
664e5dd7070Spatrick bool HasTypeConstraint) {
665e5dd7070Spatrick return new (C, ID,
666e5dd7070Spatrick additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
667*12c85518Srobert TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
668*12c85518Srobert false, HasTypeConstraint, std::nullopt);
669e5dd7070Spatrick }
670e5dd7070Spatrick
getDefaultArgumentLoc() const671e5dd7070Spatrick SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
672e5dd7070Spatrick return hasDefaultArgument()
673e5dd7070Spatrick ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
674e5dd7070Spatrick : SourceLocation();
675e5dd7070Spatrick }
676e5dd7070Spatrick
getSourceRange() const677e5dd7070Spatrick SourceRange TemplateTypeParmDecl::getSourceRange() const {
678e5dd7070Spatrick if (hasDefaultArgument() && !defaultArgumentWasInherited())
679e5dd7070Spatrick return SourceRange(getBeginLoc(),
680e5dd7070Spatrick getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
681e5dd7070Spatrick // TypeDecl::getSourceRange returns a range containing name location, which is
682e5dd7070Spatrick // wrong for unnamed template parameters. e.g:
683e5dd7070Spatrick // it will return <[[typename>]] instead of <[[typename]]>
684e5dd7070Spatrick else if (getDeclName().isEmpty())
685e5dd7070Spatrick return SourceRange(getBeginLoc());
686e5dd7070Spatrick return TypeDecl::getSourceRange();
687e5dd7070Spatrick }
688e5dd7070Spatrick
getDepth() const689e5dd7070Spatrick unsigned TemplateTypeParmDecl::getDepth() const {
690e5dd7070Spatrick return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
691e5dd7070Spatrick }
692e5dd7070Spatrick
getIndex() const693e5dd7070Spatrick unsigned TemplateTypeParmDecl::getIndex() const {
694e5dd7070Spatrick return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
695e5dd7070Spatrick }
696e5dd7070Spatrick
isParameterPack() const697e5dd7070Spatrick bool TemplateTypeParmDecl::isParameterPack() const {
698e5dd7070Spatrick return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
699e5dd7070Spatrick }
700e5dd7070Spatrick
setTypeConstraint(NestedNameSpecifierLoc NNS,DeclarationNameInfo NameInfo,NamedDecl * FoundDecl,ConceptDecl * CD,const ASTTemplateArgumentListInfo * ArgsAsWritten,Expr * ImmediatelyDeclaredConstraint)701e5dd7070Spatrick void TemplateTypeParmDecl::setTypeConstraint(NestedNameSpecifierLoc NNS,
702e5dd7070Spatrick DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD,
703e5dd7070Spatrick const ASTTemplateArgumentListInfo *ArgsAsWritten,
704e5dd7070Spatrick Expr *ImmediatelyDeclaredConstraint) {
705e5dd7070Spatrick assert(HasTypeConstraint &&
706e5dd7070Spatrick "HasTypeConstraint=true must be passed at construction in order to "
707e5dd7070Spatrick "call setTypeConstraint");
708e5dd7070Spatrick assert(!TypeConstraintInitialized &&
709e5dd7070Spatrick "TypeConstraint was already initialized!");
710e5dd7070Spatrick new (getTrailingObjects<TypeConstraint>()) TypeConstraint(NNS, NameInfo,
711e5dd7070Spatrick FoundDecl, CD, ArgsAsWritten, ImmediatelyDeclaredConstraint);
712e5dd7070Spatrick TypeConstraintInitialized = true;
713e5dd7070Spatrick }
714e5dd7070Spatrick
715e5dd7070Spatrick //===----------------------------------------------------------------------===//
716e5dd7070Spatrick // NonTypeTemplateParmDecl Method Implementations
717e5dd7070Spatrick //===----------------------------------------------------------------------===//
718e5dd7070Spatrick
NonTypeTemplateParmDecl(DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,ArrayRef<QualType> ExpandedTypes,ArrayRef<TypeSourceInfo * > ExpandedTInfos)719e5dd7070Spatrick NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
720e5dd7070Spatrick DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
721e5dd7070Spatrick unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
722e5dd7070Spatrick ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
723e5dd7070Spatrick : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
724e5dd7070Spatrick TemplateParmPosition(D, P), ParameterPack(true),
725e5dd7070Spatrick ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
726e5dd7070Spatrick if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
727e5dd7070Spatrick auto TypesAndInfos =
728e5dd7070Spatrick getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
729e5dd7070Spatrick for (unsigned I = 0; I != NumExpandedTypes; ++I) {
730e5dd7070Spatrick new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
731e5dd7070Spatrick TypesAndInfos[I].second = ExpandedTInfos[I];
732e5dd7070Spatrick }
733e5dd7070Spatrick }
734e5dd7070Spatrick }
735e5dd7070Spatrick
736e5dd7070Spatrick NonTypeTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,bool ParameterPack,TypeSourceInfo * TInfo)737e5dd7070Spatrick NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
738e5dd7070Spatrick SourceLocation StartLoc, SourceLocation IdLoc,
739e5dd7070Spatrick unsigned D, unsigned P, IdentifierInfo *Id,
740e5dd7070Spatrick QualType T, bool ParameterPack,
741e5dd7070Spatrick TypeSourceInfo *TInfo) {
742e5dd7070Spatrick AutoType *AT =
743ec727ea7Spatrick C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
744e5dd7070Spatrick return new (C, DC,
745e5dd7070Spatrick additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
746e5dd7070Spatrick Expr *>(0,
747e5dd7070Spatrick AT && AT->isConstrained() ? 1 : 0))
748e5dd7070Spatrick NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
749e5dd7070Spatrick TInfo);
750e5dd7070Spatrick }
751e5dd7070Spatrick
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,ArrayRef<QualType> ExpandedTypes,ArrayRef<TypeSourceInfo * > ExpandedTInfos)752e5dd7070Spatrick NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
753e5dd7070Spatrick const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
754e5dd7070Spatrick SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
755e5dd7070Spatrick QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
756e5dd7070Spatrick ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
757e5dd7070Spatrick AutoType *AT = TInfo->getType()->getContainedAutoType();
758e5dd7070Spatrick return new (C, DC,
759e5dd7070Spatrick additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
760e5dd7070Spatrick Expr *>(
761e5dd7070Spatrick ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
762e5dd7070Spatrick NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
763e5dd7070Spatrick ExpandedTypes, ExpandedTInfos);
764e5dd7070Spatrick }
765e5dd7070Spatrick
766e5dd7070Spatrick NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,bool HasTypeConstraint)767e5dd7070Spatrick NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
768e5dd7070Spatrick bool HasTypeConstraint) {
769e5dd7070Spatrick return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
770e5dd7070Spatrick TypeSourceInfo *>,
771e5dd7070Spatrick Expr *>(0,
772e5dd7070Spatrick HasTypeConstraint ? 1 : 0))
773e5dd7070Spatrick NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
774e5dd7070Spatrick 0, 0, nullptr, QualType(), false, nullptr);
775e5dd7070Spatrick }
776e5dd7070Spatrick
777e5dd7070Spatrick NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpandedTypes,bool HasTypeConstraint)778e5dd7070Spatrick NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
779e5dd7070Spatrick unsigned NumExpandedTypes,
780e5dd7070Spatrick bool HasTypeConstraint) {
781e5dd7070Spatrick auto *NTTP =
782*12c85518Srobert new (C, ID,
783*12c85518Srobert additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
784e5dd7070Spatrick NumExpandedTypes, HasTypeConstraint ? 1 : 0))
785e5dd7070Spatrick NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
786*12c85518Srobert 0, 0, nullptr, QualType(), nullptr,
787*12c85518Srobert std::nullopt, std::nullopt);
788e5dd7070Spatrick NTTP->NumExpandedTypes = NumExpandedTypes;
789e5dd7070Spatrick return NTTP;
790e5dd7070Spatrick }
791e5dd7070Spatrick
getSourceRange() const792e5dd7070Spatrick SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
793e5dd7070Spatrick if (hasDefaultArgument() && !defaultArgumentWasInherited())
794e5dd7070Spatrick return SourceRange(getOuterLocStart(),
795e5dd7070Spatrick getDefaultArgument()->getSourceRange().getEnd());
796e5dd7070Spatrick return DeclaratorDecl::getSourceRange();
797e5dd7070Spatrick }
798e5dd7070Spatrick
getDefaultArgumentLoc() const799e5dd7070Spatrick SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
800e5dd7070Spatrick return hasDefaultArgument()
801e5dd7070Spatrick ? getDefaultArgument()->getSourceRange().getBegin()
802e5dd7070Spatrick : SourceLocation();
803e5dd7070Spatrick }
804e5dd7070Spatrick
805e5dd7070Spatrick //===----------------------------------------------------------------------===//
806e5dd7070Spatrick // TemplateTemplateParmDecl Method Implementations
807e5dd7070Spatrick //===----------------------------------------------------------------------===//
808e5dd7070Spatrick
anchor()809e5dd7070Spatrick void TemplateTemplateParmDecl::anchor() {}
810e5dd7070Spatrick
TemplateTemplateParmDecl(DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)811e5dd7070Spatrick TemplateTemplateParmDecl::TemplateTemplateParmDecl(
812e5dd7070Spatrick DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
813e5dd7070Spatrick IdentifierInfo *Id, TemplateParameterList *Params,
814e5dd7070Spatrick ArrayRef<TemplateParameterList *> Expansions)
815e5dd7070Spatrick : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
816e5dd7070Spatrick TemplateParmPosition(D, P), ParameterPack(true),
817e5dd7070Spatrick ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
818e5dd7070Spatrick if (!Expansions.empty())
819e5dd7070Spatrick std::uninitialized_copy(Expansions.begin(), Expansions.end(),
820e5dd7070Spatrick getTrailingObjects<TemplateParameterList *>());
821e5dd7070Spatrick }
822e5dd7070Spatrick
823e5dd7070Spatrick TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,bool ParameterPack,IdentifierInfo * Id,TemplateParameterList * Params)824e5dd7070Spatrick TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
825e5dd7070Spatrick SourceLocation L, unsigned D, unsigned P,
826e5dd7070Spatrick bool ParameterPack, IdentifierInfo *Id,
827e5dd7070Spatrick TemplateParameterList *Params) {
828e5dd7070Spatrick return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
829e5dd7070Spatrick Params);
830e5dd7070Spatrick }
831e5dd7070Spatrick
832e5dd7070Spatrick TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)833e5dd7070Spatrick TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
834e5dd7070Spatrick SourceLocation L, unsigned D, unsigned P,
835e5dd7070Spatrick IdentifierInfo *Id,
836e5dd7070Spatrick TemplateParameterList *Params,
837e5dd7070Spatrick ArrayRef<TemplateParameterList *> Expansions) {
838e5dd7070Spatrick return new (C, DC,
839e5dd7070Spatrick additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
840e5dd7070Spatrick TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
841e5dd7070Spatrick }
842e5dd7070Spatrick
843e5dd7070Spatrick TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)844e5dd7070Spatrick TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
845e5dd7070Spatrick return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
846e5dd7070Spatrick false, nullptr, nullptr);
847e5dd7070Spatrick }
848e5dd7070Spatrick
849e5dd7070Spatrick TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpansions)850e5dd7070Spatrick TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
851e5dd7070Spatrick unsigned NumExpansions) {
852e5dd7070Spatrick auto *TTP =
853e5dd7070Spatrick new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
854e5dd7070Spatrick TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
855*12c85518Srobert nullptr, std::nullopt);
856e5dd7070Spatrick TTP->NumExpandedParams = NumExpansions;
857e5dd7070Spatrick return TTP;
858e5dd7070Spatrick }
859e5dd7070Spatrick
getDefaultArgumentLoc() const860e5dd7070Spatrick SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
861e5dd7070Spatrick return hasDefaultArgument() ? getDefaultArgument().getLocation()
862e5dd7070Spatrick : SourceLocation();
863e5dd7070Spatrick }
864e5dd7070Spatrick
setDefaultArgument(const ASTContext & C,const TemplateArgumentLoc & DefArg)865e5dd7070Spatrick void TemplateTemplateParmDecl::setDefaultArgument(
866e5dd7070Spatrick const ASTContext &C, const TemplateArgumentLoc &DefArg) {
867e5dd7070Spatrick if (DefArg.getArgument().isNull())
868e5dd7070Spatrick DefaultArgument.set(nullptr);
869e5dd7070Spatrick else
870e5dd7070Spatrick DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
871e5dd7070Spatrick }
872e5dd7070Spatrick
873e5dd7070Spatrick //===----------------------------------------------------------------------===//
874e5dd7070Spatrick // TemplateArgumentList Implementation
875e5dd7070Spatrick //===----------------------------------------------------------------------===//
TemplateArgumentList(ArrayRef<TemplateArgument> Args)876e5dd7070Spatrick TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
877e5dd7070Spatrick : Arguments(getTrailingObjects<TemplateArgument>()),
878e5dd7070Spatrick NumArguments(Args.size()) {
879e5dd7070Spatrick std::uninitialized_copy(Args.begin(), Args.end(),
880e5dd7070Spatrick getTrailingObjects<TemplateArgument>());
881e5dd7070Spatrick }
882e5dd7070Spatrick
883e5dd7070Spatrick TemplateArgumentList *
CreateCopy(ASTContext & Context,ArrayRef<TemplateArgument> Args)884e5dd7070Spatrick TemplateArgumentList::CreateCopy(ASTContext &Context,
885e5dd7070Spatrick ArrayRef<TemplateArgument> Args) {
886e5dd7070Spatrick void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
887e5dd7070Spatrick return new (Mem) TemplateArgumentList(Args);
888e5dd7070Spatrick }
889e5dd7070Spatrick
Create(ASTContext & C,FunctionDecl * FD,FunctionTemplateDecl * Template,TemplateSpecializationKind TSK,const TemplateArgumentList * TemplateArgs,const TemplateArgumentListInfo * TemplateArgsAsWritten,SourceLocation POI,MemberSpecializationInfo * MSInfo)890e5dd7070Spatrick FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
891e5dd7070Spatrick ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
892e5dd7070Spatrick TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
893e5dd7070Spatrick const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
894e5dd7070Spatrick MemberSpecializationInfo *MSInfo) {
895e5dd7070Spatrick const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
896e5dd7070Spatrick if (TemplateArgsAsWritten)
897e5dd7070Spatrick ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
898e5dd7070Spatrick *TemplateArgsAsWritten);
899e5dd7070Spatrick
900e5dd7070Spatrick void *Mem =
901e5dd7070Spatrick C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
902e5dd7070Spatrick return new (Mem) FunctionTemplateSpecializationInfo(
903e5dd7070Spatrick FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
904e5dd7070Spatrick }
905e5dd7070Spatrick
906e5dd7070Spatrick //===----------------------------------------------------------------------===//
907e5dd7070Spatrick // ClassTemplateSpecializationDecl Implementation
908e5dd7070Spatrick //===----------------------------------------------------------------------===//
909e5dd7070Spatrick
910e5dd7070Spatrick ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext & Context,Kind DK,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)911e5dd7070Spatrick ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
912e5dd7070Spatrick DeclContext *DC, SourceLocation StartLoc,
913e5dd7070Spatrick SourceLocation IdLoc,
914e5dd7070Spatrick ClassTemplateDecl *SpecializedTemplate,
915e5dd7070Spatrick ArrayRef<TemplateArgument> Args,
916e5dd7070Spatrick ClassTemplateSpecializationDecl *PrevDecl)
917e5dd7070Spatrick : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
918e5dd7070Spatrick SpecializedTemplate->getIdentifier(), PrevDecl),
919e5dd7070Spatrick SpecializedTemplate(SpecializedTemplate),
920e5dd7070Spatrick TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
921e5dd7070Spatrick SpecializationKind(TSK_Undeclared) {
922e5dd7070Spatrick }
923e5dd7070Spatrick
ClassTemplateSpecializationDecl(ASTContext & C,Kind DK)924e5dd7070Spatrick ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
925e5dd7070Spatrick Kind DK)
926e5dd7070Spatrick : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
927e5dd7070Spatrick SourceLocation(), nullptr, nullptr),
928e5dd7070Spatrick SpecializationKind(TSK_Undeclared) {}
929e5dd7070Spatrick
930e5dd7070Spatrick ClassTemplateSpecializationDecl *
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)931e5dd7070Spatrick ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
932e5dd7070Spatrick DeclContext *DC,
933e5dd7070Spatrick SourceLocation StartLoc,
934e5dd7070Spatrick SourceLocation IdLoc,
935e5dd7070Spatrick ClassTemplateDecl *SpecializedTemplate,
936e5dd7070Spatrick ArrayRef<TemplateArgument> Args,
937e5dd7070Spatrick ClassTemplateSpecializationDecl *PrevDecl) {
938e5dd7070Spatrick auto *Result =
939e5dd7070Spatrick new (Context, DC) ClassTemplateSpecializationDecl(
940e5dd7070Spatrick Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
941e5dd7070Spatrick SpecializedTemplate, Args, PrevDecl);
942e5dd7070Spatrick Result->setMayHaveOutOfDateDef(false);
943e5dd7070Spatrick
944*12c85518Srobert // If the template decl is incomplete, copy the external lexical storage from
945*12c85518Srobert // the base template. This allows instantiations of incomplete types to
946*12c85518Srobert // complete using the external AST if the template's declaration came from an
947*12c85518Srobert // external AST.
948*12c85518Srobert if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
949*12c85518Srobert Result->setHasExternalLexicalStorage(
950*12c85518Srobert SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
951*12c85518Srobert
952e5dd7070Spatrick Context.getTypeDeclType(Result, PrevDecl);
953e5dd7070Spatrick return Result;
954e5dd7070Spatrick }
955e5dd7070Spatrick
956e5dd7070Spatrick ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)957e5dd7070Spatrick ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
958e5dd7070Spatrick unsigned ID) {
959e5dd7070Spatrick auto *Result =
960e5dd7070Spatrick new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
961e5dd7070Spatrick Result->setMayHaveOutOfDateDef(false);
962e5dd7070Spatrick return Result;
963e5dd7070Spatrick }
964e5dd7070Spatrick
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const965e5dd7070Spatrick void ClassTemplateSpecializationDecl::getNameForDiagnostic(
966e5dd7070Spatrick raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
967e5dd7070Spatrick NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
968e5dd7070Spatrick
969e5dd7070Spatrick const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
970e5dd7070Spatrick if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
971e5dd7070Spatrick PS ? PS->getTemplateArgsAsWritten() : nullptr) {
972a9ac8606Spatrick printTemplateArgumentList(
973a9ac8606Spatrick OS, ArgsAsWritten->arguments(), Policy,
974a9ac8606Spatrick getSpecializedTemplate()->getTemplateParameters());
975e5dd7070Spatrick } else {
976e5dd7070Spatrick const TemplateArgumentList &TemplateArgs = getTemplateArgs();
977a9ac8606Spatrick printTemplateArgumentList(
978a9ac8606Spatrick OS, TemplateArgs.asArray(), Policy,
979a9ac8606Spatrick getSpecializedTemplate()->getTemplateParameters());
980e5dd7070Spatrick }
981e5dd7070Spatrick }
982e5dd7070Spatrick
983e5dd7070Spatrick ClassTemplateDecl *
getSpecializedTemplate() const984e5dd7070Spatrick ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
985e5dd7070Spatrick if (const auto *PartialSpec =
986e5dd7070Spatrick SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
987e5dd7070Spatrick return PartialSpec->PartialSpecialization->getSpecializedTemplate();
988e5dd7070Spatrick return SpecializedTemplate.get<ClassTemplateDecl*>();
989e5dd7070Spatrick }
990e5dd7070Spatrick
991e5dd7070Spatrick SourceRange
getSourceRange() const992e5dd7070Spatrick ClassTemplateSpecializationDecl::getSourceRange() const {
993e5dd7070Spatrick if (ExplicitInfo) {
994e5dd7070Spatrick SourceLocation Begin = getTemplateKeywordLoc();
995e5dd7070Spatrick if (Begin.isValid()) {
996e5dd7070Spatrick // Here we have an explicit (partial) specialization or instantiation.
997e5dd7070Spatrick assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
998e5dd7070Spatrick getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
999e5dd7070Spatrick getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
1000e5dd7070Spatrick if (getExternLoc().isValid())
1001e5dd7070Spatrick Begin = getExternLoc();
1002e5dd7070Spatrick SourceLocation End = getBraceRange().getEnd();
1003e5dd7070Spatrick if (End.isInvalid())
1004e5dd7070Spatrick End = getTypeAsWritten()->getTypeLoc().getEndLoc();
1005e5dd7070Spatrick return SourceRange(Begin, End);
1006e5dd7070Spatrick }
1007e5dd7070Spatrick // An implicit instantiation of a class template partial specialization
1008e5dd7070Spatrick // uses ExplicitInfo to record the TypeAsWritten, but the source
1009e5dd7070Spatrick // locations should be retrieved from the instantiation pattern.
1010e5dd7070Spatrick using CTPSDecl = ClassTemplatePartialSpecializationDecl;
1011e5dd7070Spatrick auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
1012e5dd7070Spatrick CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
1013e5dd7070Spatrick assert(inst_from != nullptr);
1014e5dd7070Spatrick return inst_from->getSourceRange();
1015e5dd7070Spatrick }
1016e5dd7070Spatrick else {
1017e5dd7070Spatrick // No explicit info available.
1018e5dd7070Spatrick llvm::PointerUnion<ClassTemplateDecl *,
1019e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *>
1020e5dd7070Spatrick inst_from = getInstantiatedFrom();
1021e5dd7070Spatrick if (inst_from.isNull())
1022e5dd7070Spatrick return getSpecializedTemplate()->getSourceRange();
1023e5dd7070Spatrick if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
1024e5dd7070Spatrick return ctd->getSourceRange();
1025e5dd7070Spatrick return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
1026e5dd7070Spatrick ->getSourceRange();
1027e5dd7070Spatrick }
1028e5dd7070Spatrick }
1029e5dd7070Spatrick
1030e5dd7070Spatrick //===----------------------------------------------------------------------===//
1031e5dd7070Spatrick // ConceptDecl Implementation
1032e5dd7070Spatrick //===----------------------------------------------------------------------===//
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,Expr * ConstraintExpr)1033e5dd7070Spatrick ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1034e5dd7070Spatrick SourceLocation L, DeclarationName Name,
1035e5dd7070Spatrick TemplateParameterList *Params,
1036e5dd7070Spatrick Expr *ConstraintExpr) {
1037*12c85518Srobert bool Invalid = AdoptTemplateParameterList(Params, DC);
1038*12c85518Srobert auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1039*12c85518Srobert if (Invalid)
1040*12c85518Srobert TD->setInvalidDecl();
1041*12c85518Srobert return TD;
1042e5dd7070Spatrick }
1043e5dd7070Spatrick
CreateDeserialized(ASTContext & C,unsigned ID)1044e5dd7070Spatrick ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
1045e5dd7070Spatrick unsigned ID) {
1046e5dd7070Spatrick ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1047e5dd7070Spatrick DeclarationName(),
1048e5dd7070Spatrick nullptr, nullptr);
1049e5dd7070Spatrick
1050e5dd7070Spatrick return Result;
1051e5dd7070Spatrick }
1052e5dd7070Spatrick
1053e5dd7070Spatrick //===----------------------------------------------------------------------===//
1054*12c85518Srobert // ImplicitConceptSpecializationDecl Implementation
1055*12c85518Srobert //===----------------------------------------------------------------------===//
ImplicitConceptSpecializationDecl(DeclContext * DC,SourceLocation SL,ArrayRef<TemplateArgument> ConvertedArgs)1056*12c85518Srobert ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1057*12c85518Srobert DeclContext *DC, SourceLocation SL,
1058*12c85518Srobert ArrayRef<TemplateArgument> ConvertedArgs)
1059*12c85518Srobert : Decl(ImplicitConceptSpecialization, DC, SL),
1060*12c85518Srobert NumTemplateArgs(ConvertedArgs.size()) {
1061*12c85518Srobert setTemplateArguments(ConvertedArgs);
1062*12c85518Srobert }
1063*12c85518Srobert
ImplicitConceptSpecializationDecl(EmptyShell Empty,unsigned NumTemplateArgs)1064*12c85518Srobert ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1065*12c85518Srobert EmptyShell Empty, unsigned NumTemplateArgs)
1066*12c85518Srobert : Decl(ImplicitConceptSpecialization, Empty),
1067*12c85518Srobert NumTemplateArgs(NumTemplateArgs) {}
1068*12c85518Srobert
Create(const ASTContext & C,DeclContext * DC,SourceLocation SL,ArrayRef<TemplateArgument> ConvertedArgs)1069*12c85518Srobert ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1070*12c85518Srobert const ASTContext &C, DeclContext *DC, SourceLocation SL,
1071*12c85518Srobert ArrayRef<TemplateArgument> ConvertedArgs) {
1072*12c85518Srobert return new (C, DC,
1073*12c85518Srobert additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1074*12c85518Srobert ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1075*12c85518Srobert }
1076*12c85518Srobert
1077*12c85518Srobert ImplicitConceptSpecializationDecl *
CreateDeserialized(const ASTContext & C,unsigned ID,unsigned NumTemplateArgs)1078*12c85518Srobert ImplicitConceptSpecializationDecl::CreateDeserialized(
1079*12c85518Srobert const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) {
1080*12c85518Srobert return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1081*12c85518Srobert ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1082*12c85518Srobert }
1083*12c85518Srobert
setTemplateArguments(ArrayRef<TemplateArgument> Converted)1084*12c85518Srobert void ImplicitConceptSpecializationDecl::setTemplateArguments(
1085*12c85518Srobert ArrayRef<TemplateArgument> Converted) {
1086*12c85518Srobert assert(Converted.size() == NumTemplateArgs);
1087*12c85518Srobert std::uninitialized_copy(Converted.begin(), Converted.end(),
1088*12c85518Srobert getTrailingObjects<TemplateArgument>());
1089*12c85518Srobert }
1090*12c85518Srobert
1091*12c85518Srobert //===----------------------------------------------------------------------===//
1092e5dd7070Spatrick // ClassTemplatePartialSpecializationDecl Implementation
1093e5dd7070Spatrick //===----------------------------------------------------------------------===//
anchor()1094e5dd7070Spatrick void ClassTemplatePartialSpecializationDecl::anchor() {}
1095e5dd7070Spatrick
1096e5dd7070Spatrick ClassTemplatePartialSpecializationDecl::
ClassTemplatePartialSpecializationDecl(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,const ASTTemplateArgumentListInfo * ArgInfos,ClassTemplatePartialSpecializationDecl * PrevDecl)1097e5dd7070Spatrick ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1098e5dd7070Spatrick DeclContext *DC,
1099e5dd7070Spatrick SourceLocation StartLoc,
1100e5dd7070Spatrick SourceLocation IdLoc,
1101e5dd7070Spatrick TemplateParameterList *Params,
1102e5dd7070Spatrick ClassTemplateDecl *SpecializedTemplate,
1103e5dd7070Spatrick ArrayRef<TemplateArgument> Args,
1104e5dd7070Spatrick const ASTTemplateArgumentListInfo *ArgInfos,
1105e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *PrevDecl)
1106e5dd7070Spatrick : ClassTemplateSpecializationDecl(Context,
1107e5dd7070Spatrick ClassTemplatePartialSpecialization,
1108e5dd7070Spatrick TK, DC, StartLoc, IdLoc,
1109e5dd7070Spatrick SpecializedTemplate, Args, PrevDecl),
1110e5dd7070Spatrick TemplateParams(Params), ArgsAsWritten(ArgInfos),
1111e5dd7070Spatrick InstantiatedFromMember(nullptr, false) {
1112*12c85518Srobert if (AdoptTemplateParameterList(Params, this))
1113*12c85518Srobert setInvalidDecl();
1114e5dd7070Spatrick }
1115e5dd7070Spatrick
1116e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *
1117e5dd7070Spatrick ClassTemplatePartialSpecializationDecl::
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,const TemplateArgumentListInfo & ArgInfos,QualType CanonInjectedType,ClassTemplatePartialSpecializationDecl * PrevDecl)1118e5dd7070Spatrick Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1119e5dd7070Spatrick SourceLocation StartLoc, SourceLocation IdLoc,
1120e5dd7070Spatrick TemplateParameterList *Params,
1121e5dd7070Spatrick ClassTemplateDecl *SpecializedTemplate,
1122e5dd7070Spatrick ArrayRef<TemplateArgument> Args,
1123e5dd7070Spatrick const TemplateArgumentListInfo &ArgInfos,
1124e5dd7070Spatrick QualType CanonInjectedType,
1125e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *PrevDecl) {
1126e5dd7070Spatrick const ASTTemplateArgumentListInfo *ASTArgInfos =
1127e5dd7070Spatrick ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1128e5dd7070Spatrick
1129e5dd7070Spatrick auto *Result = new (Context, DC)
1130e5dd7070Spatrick ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
1131e5dd7070Spatrick Params, SpecializedTemplate, Args,
1132e5dd7070Spatrick ASTArgInfos, PrevDecl);
1133e5dd7070Spatrick Result->setSpecializationKind(TSK_ExplicitSpecialization);
1134e5dd7070Spatrick Result->setMayHaveOutOfDateDef(false);
1135e5dd7070Spatrick
1136e5dd7070Spatrick Context.getInjectedClassNameType(Result, CanonInjectedType);
1137e5dd7070Spatrick return Result;
1138e5dd7070Spatrick }
1139e5dd7070Spatrick
1140e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1141e5dd7070Spatrick ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1142e5dd7070Spatrick unsigned ID) {
1143e5dd7070Spatrick auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1144e5dd7070Spatrick Result->setMayHaveOutOfDateDef(false);
1145e5dd7070Spatrick return Result;
1146e5dd7070Spatrick }
1147e5dd7070Spatrick
1148e5dd7070Spatrick //===----------------------------------------------------------------------===//
1149e5dd7070Spatrick // FriendTemplateDecl Implementation
1150e5dd7070Spatrick //===----------------------------------------------------------------------===//
1151e5dd7070Spatrick
anchor()1152e5dd7070Spatrick void FriendTemplateDecl::anchor() {}
1153e5dd7070Spatrick
1154e5dd7070Spatrick FriendTemplateDecl *
Create(ASTContext & Context,DeclContext * DC,SourceLocation L,MutableArrayRef<TemplateParameterList * > Params,FriendUnion Friend,SourceLocation FLoc)1155e5dd7070Spatrick FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1156e5dd7070Spatrick SourceLocation L,
1157e5dd7070Spatrick MutableArrayRef<TemplateParameterList *> Params,
1158e5dd7070Spatrick FriendUnion Friend, SourceLocation FLoc) {
1159*12c85518Srobert TemplateParameterList **TPL = nullptr;
1160*12c85518Srobert if (!Params.empty()) {
1161*12c85518Srobert TPL = new (Context) TemplateParameterList *[Params.size()];
1162*12c85518Srobert llvm::copy(Params, TPL);
1163*12c85518Srobert }
1164*12c85518Srobert return new (Context, DC)
1165*12c85518Srobert FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1166e5dd7070Spatrick }
1167e5dd7070Spatrick
CreateDeserialized(ASTContext & C,unsigned ID)1168e5dd7070Spatrick FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1169e5dd7070Spatrick unsigned ID) {
1170e5dd7070Spatrick return new (C, ID) FriendTemplateDecl(EmptyShell());
1171e5dd7070Spatrick }
1172e5dd7070Spatrick
1173e5dd7070Spatrick //===----------------------------------------------------------------------===//
1174e5dd7070Spatrick // TypeAliasTemplateDecl Implementation
1175e5dd7070Spatrick //===----------------------------------------------------------------------===//
1176e5dd7070Spatrick
1177*12c85518Srobert TypeAliasTemplateDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)1178*12c85518Srobert TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1179e5dd7070Spatrick DeclarationName Name,
1180*12c85518Srobert TemplateParameterList *Params, NamedDecl *Decl) {
1181*12c85518Srobert bool Invalid = AdoptTemplateParameterList(Params, DC);
1182*12c85518Srobert auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1183*12c85518Srobert if (Invalid)
1184*12c85518Srobert TD->setInvalidDecl();
1185*12c85518Srobert return TD;
1186e5dd7070Spatrick }
1187e5dd7070Spatrick
CreateDeserialized(ASTContext & C,unsigned ID)1188e5dd7070Spatrick TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
1189e5dd7070Spatrick unsigned ID) {
1190e5dd7070Spatrick return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1191e5dd7070Spatrick DeclarationName(), nullptr, nullptr);
1192e5dd7070Spatrick }
1193e5dd7070Spatrick
1194e5dd7070Spatrick RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const1195e5dd7070Spatrick TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1196e5dd7070Spatrick auto *CommonPtr = new (C) Common;
1197e5dd7070Spatrick C.addDestruction(CommonPtr);
1198e5dd7070Spatrick return CommonPtr;
1199e5dd7070Spatrick }
1200e5dd7070Spatrick
1201e5dd7070Spatrick //===----------------------------------------------------------------------===//
1202e5dd7070Spatrick // ClassScopeFunctionSpecializationDecl Implementation
1203e5dd7070Spatrick //===----------------------------------------------------------------------===//
1204e5dd7070Spatrick
anchor()1205e5dd7070Spatrick void ClassScopeFunctionSpecializationDecl::anchor() {}
1206e5dd7070Spatrick
1207e5dd7070Spatrick ClassScopeFunctionSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1208e5dd7070Spatrick ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
1209e5dd7070Spatrick unsigned ID) {
1210e5dd7070Spatrick return new (C, ID) ClassScopeFunctionSpecializationDecl(
1211e5dd7070Spatrick nullptr, SourceLocation(), nullptr, nullptr);
1212e5dd7070Spatrick }
1213e5dd7070Spatrick
1214e5dd7070Spatrick //===----------------------------------------------------------------------===//
1215e5dd7070Spatrick // VarTemplateDecl Implementation
1216e5dd7070Spatrick //===----------------------------------------------------------------------===//
1217e5dd7070Spatrick
getDefinition()1218e5dd7070Spatrick VarTemplateDecl *VarTemplateDecl::getDefinition() {
1219e5dd7070Spatrick VarTemplateDecl *CurD = this;
1220e5dd7070Spatrick while (CurD) {
1221e5dd7070Spatrick if (CurD->isThisDeclarationADefinition())
1222e5dd7070Spatrick return CurD;
1223e5dd7070Spatrick CurD = CurD->getPreviousDecl();
1224e5dd7070Spatrick }
1225e5dd7070Spatrick return nullptr;
1226e5dd7070Spatrick }
1227e5dd7070Spatrick
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,VarDecl * Decl)1228e5dd7070Spatrick VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1229e5dd7070Spatrick SourceLocation L, DeclarationName Name,
1230e5dd7070Spatrick TemplateParameterList *Params,
1231e5dd7070Spatrick VarDecl *Decl) {
1232*12c85518Srobert bool Invalid = AdoptTemplateParameterList(Params, DC);
1233*12c85518Srobert auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1234*12c85518Srobert if (Invalid)
1235*12c85518Srobert TD->setInvalidDecl();
1236*12c85518Srobert return TD;
1237e5dd7070Spatrick }
1238e5dd7070Spatrick
CreateDeserialized(ASTContext & C,unsigned ID)1239e5dd7070Spatrick VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1240e5dd7070Spatrick unsigned ID) {
1241e5dd7070Spatrick return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1242e5dd7070Spatrick DeclarationName(), nullptr, nullptr);
1243e5dd7070Spatrick }
1244e5dd7070Spatrick
LoadLazySpecializations() const1245e5dd7070Spatrick void VarTemplateDecl::LoadLazySpecializations() const {
1246e5dd7070Spatrick loadLazySpecializationsImpl();
1247e5dd7070Spatrick }
1248e5dd7070Spatrick
1249e5dd7070Spatrick llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
getSpecializations() const1250e5dd7070Spatrick VarTemplateDecl::getSpecializations() const {
1251e5dd7070Spatrick LoadLazySpecializations();
1252e5dd7070Spatrick return getCommonPtr()->Specializations;
1253e5dd7070Spatrick }
1254e5dd7070Spatrick
1255e5dd7070Spatrick llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations() const1256a9ac8606Spatrick VarTemplateDecl::getPartialSpecializations() const {
1257e5dd7070Spatrick LoadLazySpecializations();
1258e5dd7070Spatrick return getCommonPtr()->PartialSpecializations;
1259e5dd7070Spatrick }
1260e5dd7070Spatrick
1261e5dd7070Spatrick RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const1262e5dd7070Spatrick VarTemplateDecl::newCommon(ASTContext &C) const {
1263e5dd7070Spatrick auto *CommonPtr = new (C) Common;
1264e5dd7070Spatrick C.addDestruction(CommonPtr);
1265e5dd7070Spatrick return CommonPtr;
1266e5dd7070Spatrick }
1267e5dd7070Spatrick
1268e5dd7070Spatrick VarTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)1269e5dd7070Spatrick VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1270e5dd7070Spatrick void *&InsertPos) {
1271e5dd7070Spatrick return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1272e5dd7070Spatrick }
1273e5dd7070Spatrick
AddSpecialization(VarTemplateSpecializationDecl * D,void * InsertPos)1274e5dd7070Spatrick void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1275e5dd7070Spatrick void *InsertPos) {
1276e5dd7070Spatrick addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1277e5dd7070Spatrick }
1278e5dd7070Spatrick
1279e5dd7070Spatrick VarTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,TemplateParameterList * TPL,void * & InsertPos)1280e5dd7070Spatrick VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1281e5dd7070Spatrick TemplateParameterList *TPL, void *&InsertPos) {
1282e5dd7070Spatrick return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1283e5dd7070Spatrick TPL);
1284e5dd7070Spatrick }
1285e5dd7070Spatrick
1286e5dd7070Spatrick void
Profile(llvm::FoldingSetNodeID & ID,ArrayRef<TemplateArgument> TemplateArgs,TemplateParameterList * TPL,ASTContext & Context)1287e5dd7070Spatrick VarTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
1288e5dd7070Spatrick ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
1289e5dd7070Spatrick ASTContext &Context) {
1290e5dd7070Spatrick ID.AddInteger(TemplateArgs.size());
1291e5dd7070Spatrick for (const TemplateArgument &TemplateArg : TemplateArgs)
1292e5dd7070Spatrick TemplateArg.Profile(ID, Context);
1293e5dd7070Spatrick ProfileTemplateParameterList(Context, ID, TPL);
1294e5dd7070Spatrick }
1295e5dd7070Spatrick
AddPartialSpecialization(VarTemplatePartialSpecializationDecl * D,void * InsertPos)1296e5dd7070Spatrick void VarTemplateDecl::AddPartialSpecialization(
1297e5dd7070Spatrick VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1298e5dd7070Spatrick if (InsertPos)
1299e5dd7070Spatrick getPartialSpecializations().InsertNode(D, InsertPos);
1300e5dd7070Spatrick else {
1301e5dd7070Spatrick VarTemplatePartialSpecializationDecl *Existing =
1302e5dd7070Spatrick getPartialSpecializations().GetOrInsertNode(D);
1303e5dd7070Spatrick (void)Existing;
1304e5dd7070Spatrick assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1305e5dd7070Spatrick }
1306e5dd7070Spatrick
1307e5dd7070Spatrick if (ASTMutationListener *L = getASTMutationListener())
1308e5dd7070Spatrick L->AddedCXXTemplateSpecialization(this, D);
1309e5dd7070Spatrick }
1310e5dd7070Spatrick
getPartialSpecializations(SmallVectorImpl<VarTemplatePartialSpecializationDecl * > & PS) const1311e5dd7070Spatrick void VarTemplateDecl::getPartialSpecializations(
1312a9ac8606Spatrick SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1313e5dd7070Spatrick llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1314e5dd7070Spatrick getPartialSpecializations();
1315e5dd7070Spatrick PS.clear();
1316e5dd7070Spatrick PS.reserve(PartialSpecs.size());
1317e5dd7070Spatrick for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1318e5dd7070Spatrick PS.push_back(P.getMostRecentDecl());
1319e5dd7070Spatrick }
1320e5dd7070Spatrick
1321e5dd7070Spatrick VarTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl * D)1322e5dd7070Spatrick VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1323e5dd7070Spatrick VarTemplatePartialSpecializationDecl *D) {
1324e5dd7070Spatrick Decl *DCanon = D->getCanonicalDecl();
1325e5dd7070Spatrick for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1326e5dd7070Spatrick if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1327e5dd7070Spatrick return P.getMostRecentDecl();
1328e5dd7070Spatrick }
1329e5dd7070Spatrick
1330e5dd7070Spatrick return nullptr;
1331e5dd7070Spatrick }
1332e5dd7070Spatrick
1333e5dd7070Spatrick //===----------------------------------------------------------------------===//
1334e5dd7070Spatrick // VarTemplateSpecializationDecl Implementation
1335e5dd7070Spatrick //===----------------------------------------------------------------------===//
1336e5dd7070Spatrick
VarTemplateSpecializationDecl(Kind DK,ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1337e5dd7070Spatrick VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1338e5dd7070Spatrick Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1339e5dd7070Spatrick SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1340e5dd7070Spatrick TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1341e5dd7070Spatrick : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1342e5dd7070Spatrick SpecializedTemplate->getIdentifier(), T, TInfo, S),
1343e5dd7070Spatrick SpecializedTemplate(SpecializedTemplate),
1344e5dd7070Spatrick TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1345e5dd7070Spatrick SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1346e5dd7070Spatrick
VarTemplateSpecializationDecl(Kind DK,ASTContext & C)1347e5dd7070Spatrick VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1348e5dd7070Spatrick ASTContext &C)
1349e5dd7070Spatrick : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1350e5dd7070Spatrick QualType(), nullptr, SC_None),
1351e5dd7070Spatrick SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1352e5dd7070Spatrick
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1353e5dd7070Spatrick VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1354e5dd7070Spatrick ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1355e5dd7070Spatrick SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1356e5dd7070Spatrick TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1357e5dd7070Spatrick return new (Context, DC) VarTemplateSpecializationDecl(
1358e5dd7070Spatrick VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1359e5dd7070Spatrick SpecializedTemplate, T, TInfo, S, Args);
1360e5dd7070Spatrick }
1361e5dd7070Spatrick
1362e5dd7070Spatrick VarTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1363e5dd7070Spatrick VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1364e5dd7070Spatrick return new (C, ID)
1365e5dd7070Spatrick VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1366e5dd7070Spatrick }
1367e5dd7070Spatrick
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const1368e5dd7070Spatrick void VarTemplateSpecializationDecl::getNameForDiagnostic(
1369e5dd7070Spatrick raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1370e5dd7070Spatrick NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1371e5dd7070Spatrick
1372e5dd7070Spatrick const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1373e5dd7070Spatrick if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1374e5dd7070Spatrick PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1375a9ac8606Spatrick printTemplateArgumentList(
1376a9ac8606Spatrick OS, ArgsAsWritten->arguments(), Policy,
1377a9ac8606Spatrick getSpecializedTemplate()->getTemplateParameters());
1378e5dd7070Spatrick } else {
1379e5dd7070Spatrick const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1380a9ac8606Spatrick printTemplateArgumentList(
1381a9ac8606Spatrick OS, TemplateArgs.asArray(), Policy,
1382a9ac8606Spatrick getSpecializedTemplate()->getTemplateParameters());
1383e5dd7070Spatrick }
1384e5dd7070Spatrick }
1385e5dd7070Spatrick
getSpecializedTemplate() const1386e5dd7070Spatrick VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1387e5dd7070Spatrick if (const auto *PartialSpec =
1388e5dd7070Spatrick SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1389e5dd7070Spatrick return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1390e5dd7070Spatrick return SpecializedTemplate.get<VarTemplateDecl *>();
1391e5dd7070Spatrick }
1392e5dd7070Spatrick
setTemplateArgsInfo(const TemplateArgumentListInfo & ArgsInfo)1393e5dd7070Spatrick void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1394e5dd7070Spatrick const TemplateArgumentListInfo &ArgsInfo) {
1395*12c85518Srobert TemplateArgsInfo =
1396*12c85518Srobert ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1397*12c85518Srobert }
1398*12c85518Srobert
setTemplateArgsInfo(const ASTTemplateArgumentListInfo * ArgsInfo)1399*12c85518Srobert void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1400*12c85518Srobert const ASTTemplateArgumentListInfo *ArgsInfo) {
1401*12c85518Srobert TemplateArgsInfo =
1402*12c85518Srobert ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1403e5dd7070Spatrick }
1404e5dd7070Spatrick
1405e5dd7070Spatrick //===----------------------------------------------------------------------===//
1406e5dd7070Spatrick // VarTemplatePartialSpecializationDecl Implementation
1407e5dd7070Spatrick //===----------------------------------------------------------------------===//
1408e5dd7070Spatrick
anchor()1409e5dd7070Spatrick void VarTemplatePartialSpecializationDecl::anchor() {}
1410e5dd7070Spatrick
VarTemplatePartialSpecializationDecl(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args,const ASTTemplateArgumentListInfo * ArgInfos)1411e5dd7070Spatrick VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1412e5dd7070Spatrick ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1413e5dd7070Spatrick SourceLocation IdLoc, TemplateParameterList *Params,
1414e5dd7070Spatrick VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1415e5dd7070Spatrick StorageClass S, ArrayRef<TemplateArgument> Args,
1416e5dd7070Spatrick const ASTTemplateArgumentListInfo *ArgInfos)
1417e5dd7070Spatrick : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1418e5dd7070Spatrick DC, StartLoc, IdLoc, SpecializedTemplate, T,
1419e5dd7070Spatrick TInfo, S, Args),
1420e5dd7070Spatrick TemplateParams(Params), ArgsAsWritten(ArgInfos),
1421e5dd7070Spatrick InstantiatedFromMember(nullptr, false) {
1422*12c85518Srobert if (AdoptTemplateParameterList(Params, DC))
1423*12c85518Srobert setInvalidDecl();
1424e5dd7070Spatrick }
1425e5dd7070Spatrick
1426e5dd7070Spatrick VarTemplatePartialSpecializationDecl *
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args,const TemplateArgumentListInfo & ArgInfos)1427e5dd7070Spatrick VarTemplatePartialSpecializationDecl::Create(
1428e5dd7070Spatrick ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1429e5dd7070Spatrick SourceLocation IdLoc, TemplateParameterList *Params,
1430e5dd7070Spatrick VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1431e5dd7070Spatrick StorageClass S, ArrayRef<TemplateArgument> Args,
1432e5dd7070Spatrick const TemplateArgumentListInfo &ArgInfos) {
1433e5dd7070Spatrick const ASTTemplateArgumentListInfo *ASTArgInfos
1434e5dd7070Spatrick = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1435e5dd7070Spatrick
1436e5dd7070Spatrick auto *Result =
1437e5dd7070Spatrick new (Context, DC) VarTemplatePartialSpecializationDecl(
1438e5dd7070Spatrick Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1439e5dd7070Spatrick S, Args, ASTArgInfos);
1440e5dd7070Spatrick Result->setSpecializationKind(TSK_ExplicitSpecialization);
1441e5dd7070Spatrick return Result;
1442e5dd7070Spatrick }
1443e5dd7070Spatrick
1444e5dd7070Spatrick VarTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1445e5dd7070Spatrick VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1446e5dd7070Spatrick unsigned ID) {
1447e5dd7070Spatrick return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1448e5dd7070Spatrick }
1449e5dd7070Spatrick
1450e5dd7070Spatrick static TemplateParameterList *
createMakeIntegerSeqParameterList(const ASTContext & C,DeclContext * DC)1451e5dd7070Spatrick createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1452e5dd7070Spatrick // typename T
1453e5dd7070Spatrick auto *T = TemplateTypeParmDecl::Create(
1454e5dd7070Spatrick C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1455e5dd7070Spatrick /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1456e5dd7070Spatrick /*HasTypeConstraint=*/false);
1457e5dd7070Spatrick T->setImplicit(true);
1458e5dd7070Spatrick
1459e5dd7070Spatrick // T ...Ints
1460e5dd7070Spatrick TypeSourceInfo *TI =
1461e5dd7070Spatrick C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1462e5dd7070Spatrick auto *N = NonTypeTemplateParmDecl::Create(
1463e5dd7070Spatrick C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1464e5dd7070Spatrick /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1465e5dd7070Spatrick N->setImplicit(true);
1466e5dd7070Spatrick
1467e5dd7070Spatrick // <typename T, T ...Ints>
1468e5dd7070Spatrick NamedDecl *P[2] = {T, N};
1469e5dd7070Spatrick auto *TPL = TemplateParameterList::Create(
1470e5dd7070Spatrick C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1471e5dd7070Spatrick
1472e5dd7070Spatrick // template <typename T, ...Ints> class IntSeq
1473e5dd7070Spatrick auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1474e5dd7070Spatrick C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1475e5dd7070Spatrick /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1476e5dd7070Spatrick TemplateTemplateParm->setImplicit(true);
1477e5dd7070Spatrick
1478e5dd7070Spatrick // typename T
1479e5dd7070Spatrick auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1480e5dd7070Spatrick C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1481e5dd7070Spatrick /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1482e5dd7070Spatrick /*HasTypeConstraint=*/false);
1483e5dd7070Spatrick TemplateTypeParm->setImplicit(true);
1484e5dd7070Spatrick
1485e5dd7070Spatrick // T N
1486e5dd7070Spatrick TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1487e5dd7070Spatrick QualType(TemplateTypeParm->getTypeForDecl(), 0));
1488e5dd7070Spatrick auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1489e5dd7070Spatrick C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1490e5dd7070Spatrick /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1491e5dd7070Spatrick NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1492e5dd7070Spatrick NonTypeTemplateParm};
1493e5dd7070Spatrick
1494e5dd7070Spatrick // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1495e5dd7070Spatrick return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1496e5dd7070Spatrick Params, SourceLocation(), nullptr);
1497e5dd7070Spatrick }
1498e5dd7070Spatrick
1499e5dd7070Spatrick static TemplateParameterList *
createTypePackElementParameterList(const ASTContext & C,DeclContext * DC)1500e5dd7070Spatrick createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1501e5dd7070Spatrick // std::size_t Index
1502e5dd7070Spatrick TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1503e5dd7070Spatrick auto *Index = NonTypeTemplateParmDecl::Create(
1504e5dd7070Spatrick C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1505e5dd7070Spatrick /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1506e5dd7070Spatrick
1507e5dd7070Spatrick // typename ...T
1508e5dd7070Spatrick auto *Ts = TemplateTypeParmDecl::Create(
1509e5dd7070Spatrick C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1510e5dd7070Spatrick /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1511e5dd7070Spatrick /*HasTypeConstraint=*/false);
1512e5dd7070Spatrick Ts->setImplicit(true);
1513e5dd7070Spatrick
1514e5dd7070Spatrick // template <std::size_t Index, typename ...T>
1515e5dd7070Spatrick NamedDecl *Params[] = {Index, Ts};
1516e5dd7070Spatrick return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1517*12c85518Srobert llvm::ArrayRef(Params), SourceLocation(),
1518*12c85518Srobert nullptr);
1519e5dd7070Spatrick }
1520e5dd7070Spatrick
createBuiltinTemplateParameterList(const ASTContext & C,DeclContext * DC,BuiltinTemplateKind BTK)1521e5dd7070Spatrick static TemplateParameterList *createBuiltinTemplateParameterList(
1522e5dd7070Spatrick const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1523e5dd7070Spatrick switch (BTK) {
1524e5dd7070Spatrick case BTK__make_integer_seq:
1525e5dd7070Spatrick return createMakeIntegerSeqParameterList(C, DC);
1526e5dd7070Spatrick case BTK__type_pack_element:
1527e5dd7070Spatrick return createTypePackElementParameterList(C, DC);
1528e5dd7070Spatrick }
1529e5dd7070Spatrick
1530e5dd7070Spatrick llvm_unreachable("unhandled BuiltinTemplateKind!");
1531e5dd7070Spatrick }
1532e5dd7070Spatrick
anchor()1533e5dd7070Spatrick void BuiltinTemplateDecl::anchor() {}
1534e5dd7070Spatrick
BuiltinTemplateDecl(const ASTContext & C,DeclContext * DC,DeclarationName Name,BuiltinTemplateKind BTK)1535e5dd7070Spatrick BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1536e5dd7070Spatrick DeclarationName Name,
1537e5dd7070Spatrick BuiltinTemplateKind BTK)
1538e5dd7070Spatrick : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1539e5dd7070Spatrick createBuiltinTemplateParameterList(C, DC, BTK)),
1540e5dd7070Spatrick BTK(BTK) {}
1541e5dd7070Spatrick
print(llvm::raw_ostream & OS,PrintingPolicy Policy) const1542e5dd7070Spatrick void TypeConstraint::print(llvm::raw_ostream &OS, PrintingPolicy Policy) const {
1543e5dd7070Spatrick if (NestedNameSpec)
1544e5dd7070Spatrick NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy);
1545e5dd7070Spatrick ConceptName.printName(OS, Policy);
1546e5dd7070Spatrick if (hasExplicitTemplateArgs()) {
1547e5dd7070Spatrick OS << "<";
1548a9ac8606Spatrick // FIXME: Find corresponding parameter for argument
1549e5dd7070Spatrick for (auto &ArgLoc : ArgsAsWritten->arguments())
1550a9ac8606Spatrick ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
1551e5dd7070Spatrick OS << ">";
1552e5dd7070Spatrick }
1553e5dd7070Spatrick }
1554a9ac8606Spatrick
Create(const ASTContext & C,QualType T,const APValue & V)1555a9ac8606Spatrick TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1556a9ac8606Spatrick QualType T,
1557a9ac8606Spatrick const APValue &V) {
1558a9ac8606Spatrick DeclContext *DC = C.getTranslationUnitDecl();
1559a9ac8606Spatrick auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1560a9ac8606Spatrick C.addDestruction(&TPOD->Value);
1561a9ac8606Spatrick return TPOD;
1562a9ac8606Spatrick }
1563a9ac8606Spatrick
1564a9ac8606Spatrick TemplateParamObjectDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1565a9ac8606Spatrick TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1566a9ac8606Spatrick auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1567a9ac8606Spatrick C.addDestruction(&TPOD->Value);
1568a9ac8606Spatrick return TPOD;
1569a9ac8606Spatrick }
1570a9ac8606Spatrick
printName(llvm::raw_ostream & OS,const PrintingPolicy & Policy) const1571*12c85518Srobert void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1572*12c85518Srobert const PrintingPolicy &Policy) const {
1573a9ac8606Spatrick OS << "<template param ";
1574*12c85518Srobert printAsExpr(OS, Policy);
1575a9ac8606Spatrick OS << ">";
1576a9ac8606Spatrick }
1577a9ac8606Spatrick
printAsExpr(llvm::raw_ostream & OS) const1578a9ac8606Spatrick void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1579*12c85518Srobert printAsExpr(OS, getASTContext().getPrintingPolicy());
1580*12c85518Srobert }
1581*12c85518Srobert
printAsExpr(llvm::raw_ostream & OS,const PrintingPolicy & Policy) const1582*12c85518Srobert void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1583*12c85518Srobert const PrintingPolicy &Policy) const {
1584*12c85518Srobert getType().getUnqualifiedType().print(OS, Policy);
1585*12c85518Srobert printAsInit(OS, Policy);
1586a9ac8606Spatrick }
1587a9ac8606Spatrick
printAsInit(llvm::raw_ostream & OS) const1588a9ac8606Spatrick void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1589*12c85518Srobert printAsInit(OS, getASTContext().getPrintingPolicy());
1590*12c85518Srobert }
1591*12c85518Srobert
printAsInit(llvm::raw_ostream & OS,const PrintingPolicy & Policy) const1592*12c85518Srobert void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1593*12c85518Srobert const PrintingPolicy &Policy) const {
1594*12c85518Srobert getValue().printPretty(OS, Policy, getType(), &getASTContext());
1595*12c85518Srobert }
1596*12c85518Srobert
getReplacedTemplateParameterList(Decl * D)1597*12c85518Srobert TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
1598*12c85518Srobert switch (D->getKind()) {
1599*12c85518Srobert case Decl::Kind::ClassTemplate:
1600*12c85518Srobert return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1601*12c85518Srobert case Decl::Kind::ClassTemplateSpecialization: {
1602*12c85518Srobert const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1603*12c85518Srobert auto P = CTSD->getSpecializedTemplateOrPartial();
1604*12c85518Srobert if (const auto *CTPSD =
1605*12c85518Srobert P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1606*12c85518Srobert return CTPSD->getTemplateParameters();
1607*12c85518Srobert return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1608*12c85518Srobert }
1609*12c85518Srobert case Decl::Kind::ClassTemplatePartialSpecialization:
1610*12c85518Srobert return cast<ClassTemplatePartialSpecializationDecl>(D)
1611*12c85518Srobert ->getTemplateParameters();
1612*12c85518Srobert case Decl::Kind::TypeAliasTemplate:
1613*12c85518Srobert return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1614*12c85518Srobert case Decl::Kind::BuiltinTemplate:
1615*12c85518Srobert return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1616*12c85518Srobert case Decl::Kind::CXXDeductionGuide:
1617*12c85518Srobert case Decl::Kind::CXXConversion:
1618*12c85518Srobert case Decl::Kind::CXXConstructor:
1619*12c85518Srobert case Decl::Kind::CXXDestructor:
1620*12c85518Srobert case Decl::Kind::CXXMethod:
1621*12c85518Srobert case Decl::Kind::Function:
1622*12c85518Srobert return cast<FunctionDecl>(D)
1623*12c85518Srobert ->getTemplateSpecializationInfo()
1624*12c85518Srobert ->getTemplate()
1625*12c85518Srobert ->getTemplateParameters();
1626*12c85518Srobert case Decl::Kind::FunctionTemplate:
1627*12c85518Srobert return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1628*12c85518Srobert case Decl::Kind::VarTemplate:
1629*12c85518Srobert return cast<VarTemplateDecl>(D)->getTemplateParameters();
1630*12c85518Srobert case Decl::Kind::VarTemplateSpecialization: {
1631*12c85518Srobert const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1632*12c85518Srobert auto P = VTSD->getSpecializedTemplateOrPartial();
1633*12c85518Srobert if (const auto *VTPSD =
1634*12c85518Srobert P.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1635*12c85518Srobert return VTPSD->getTemplateParameters();
1636*12c85518Srobert return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1637*12c85518Srobert }
1638*12c85518Srobert case Decl::Kind::VarTemplatePartialSpecialization:
1639*12c85518Srobert return cast<VarTemplatePartialSpecializationDecl>(D)
1640*12c85518Srobert ->getTemplateParameters();
1641*12c85518Srobert case Decl::Kind::TemplateTemplateParm:
1642*12c85518Srobert return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1643*12c85518Srobert case Decl::Kind::Concept:
1644*12c85518Srobert return cast<ConceptDecl>(D)->getTemplateParameters();
1645*12c85518Srobert default:
1646*12c85518Srobert llvm_unreachable("Unhandled templated declaration kind");
1647*12c85518Srobert }
1648a9ac8606Spatrick }
1649