xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/DeclTemplate.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the C++ related Decl classes for templates.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTMutationListener.h"
160b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclarationName.h"
180b57cec5SDimitry Andric #include "clang/AST/Expr.h"
190b57cec5SDimitry Andric #include "clang/AST/ExternalASTSource.h"
200b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h"
210b57cec5SDimitry Andric #include "clang/AST/TemplateName.h"
220b57cec5SDimitry Andric #include "clang/AST/Type.h"
230b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
240b57cec5SDimitry Andric #include "clang/Basic/Builtins.h"
250b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
260b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
270b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
280b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h"
290b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h"
30d781ede6SDimitry Andric #include "llvm/ADT/STLExtras.h"
310b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
320b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
330b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
340b57cec5SDimitry Andric #include <algorithm>
350b57cec5SDimitry Andric #include <cassert>
360b57cec5SDimitry Andric #include <cstdint>
370b57cec5SDimitry Andric #include <memory>
38bdd1243dSDimitry Andric #include <optional>
390b57cec5SDimitry Andric #include <utility>
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric using namespace clang;
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
440b57cec5SDimitry Andric // TemplateParameterList Implementation
450b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
460b57cec5SDimitry Andric 
47480093f4SDimitry Andric 
48480093f4SDimitry Andric TemplateParameterList::TemplateParameterList(const ASTContext& C,
49480093f4SDimitry Andric                                              SourceLocation TemplateLoc,
500b57cec5SDimitry Andric                                              SourceLocation LAngleLoc,
510b57cec5SDimitry Andric                                              ArrayRef<NamedDecl *> Params,
520b57cec5SDimitry Andric                                              SourceLocation RAngleLoc,
530b57cec5SDimitry Andric                                              Expr *RequiresClause)
540b57cec5SDimitry Andric     : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
550b57cec5SDimitry Andric       NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
56480093f4SDimitry Andric       HasRequiresClause(RequiresClause != nullptr),
57480093f4SDimitry Andric       HasConstrainedParameters(false) {
580b57cec5SDimitry Andric   for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
590b57cec5SDimitry Andric     NamedDecl *P = Params[Idx];
600b57cec5SDimitry Andric     begin()[Idx] = P;
610b57cec5SDimitry Andric 
62480093f4SDimitry Andric     bool IsPack = P->isTemplateParameterPack();
63480093f4SDimitry Andric     if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
64480093f4SDimitry Andric       if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
650b57cec5SDimitry Andric         ContainsUnexpandedParameterPack = true;
66480093f4SDimitry Andric       if (NTTP->hasPlaceholderTypeConstraint())
67480093f4SDimitry Andric         HasConstrainedParameters = true;
68480093f4SDimitry Andric     } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
69480093f4SDimitry Andric       if (!IsPack &&
70480093f4SDimitry Andric           TTP->getTemplateParameters()->containsUnexpandedParameterPack())
710b57cec5SDimitry Andric         ContainsUnexpandedParameterPack = true;
72fe6060f1SDimitry Andric     } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
73fe6060f1SDimitry Andric       if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
74480093f4SDimitry Andric         if (TC->getImmediatelyDeclaredConstraint()
75480093f4SDimitry Andric             ->containsUnexpandedParameterPack())
76480093f4SDimitry Andric           ContainsUnexpandedParameterPack = true;
77fe6060f1SDimitry Andric       }
78fe6060f1SDimitry Andric       if (TTP->hasTypeConstraint())
79480093f4SDimitry Andric         HasConstrainedParameters = true;
80fe6060f1SDimitry Andric     } else {
81349cc55cSDimitry Andric       llvm_unreachable("unexpected template parameter type");
82480093f4SDimitry Andric     }
830b57cec5SDimitry Andric     // FIXME: If a default argument contains an unexpanded parameter pack, the
840b57cec5SDimitry Andric     // template parameter list does too.
850b57cec5SDimitry Andric   }
86480093f4SDimitry Andric 
87480093f4SDimitry Andric   if (HasRequiresClause) {
88a7dea167SDimitry Andric     if (RequiresClause->containsUnexpandedParameterPack())
89a7dea167SDimitry Andric       ContainsUnexpandedParameterPack = true;
90480093f4SDimitry Andric     *getTrailingObjects<Expr *>() = RequiresClause;
910b57cec5SDimitry Andric   }
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric 
94fe6060f1SDimitry Andric bool TemplateParameterList::containsUnexpandedParameterPack() const {
95fe6060f1SDimitry Andric   if (ContainsUnexpandedParameterPack)
96fe6060f1SDimitry Andric     return true;
97fe6060f1SDimitry Andric   if (!HasConstrainedParameters)
98fe6060f1SDimitry Andric     return false;
99fe6060f1SDimitry Andric 
100fe6060f1SDimitry Andric   // An implicit constrained parameter might have had a use of an unexpanded
101fe6060f1SDimitry Andric   // pack added to it after the template parameter list was created. All
102fe6060f1SDimitry Andric   // implicit parameters are at the end of the parameter list.
103fe6060f1SDimitry Andric   for (const NamedDecl *Param : llvm::reverse(asArray())) {
104fe6060f1SDimitry Andric     if (!Param->isImplicit())
105fe6060f1SDimitry Andric       break;
106fe6060f1SDimitry Andric 
107fe6060f1SDimitry Andric     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
108fe6060f1SDimitry Andric       const auto *TC = TTP->getTypeConstraint();
109fe6060f1SDimitry Andric       if (TC && TC->getImmediatelyDeclaredConstraint()
110fe6060f1SDimitry Andric                     ->containsUnexpandedParameterPack())
111fe6060f1SDimitry Andric         return true;
112fe6060f1SDimitry Andric     }
113fe6060f1SDimitry Andric   }
114fe6060f1SDimitry Andric 
115fe6060f1SDimitry Andric   return false;
116fe6060f1SDimitry Andric }
117fe6060f1SDimitry Andric 
1180b57cec5SDimitry Andric TemplateParameterList *
1190b57cec5SDimitry Andric TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
1200b57cec5SDimitry Andric                               SourceLocation LAngleLoc,
1210b57cec5SDimitry Andric                               ArrayRef<NamedDecl *> Params,
1220b57cec5SDimitry Andric                               SourceLocation RAngleLoc, Expr *RequiresClause) {
1230b57cec5SDimitry Andric   void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
1240b57cec5SDimitry Andric                              Params.size(), RequiresClause ? 1u : 0u),
1250b57cec5SDimitry Andric                          alignof(TemplateParameterList));
126480093f4SDimitry Andric   return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
1270b57cec5SDimitry Andric                                          RAngleLoc, RequiresClause);
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
13006c3fb27SDimitry Andric void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,
13106c3fb27SDimitry Andric                                     const ASTContext &C) const {
13206c3fb27SDimitry Andric   const Expr *RC = getRequiresClause();
13306c3fb27SDimitry Andric   ID.AddBoolean(RC != nullptr);
13406c3fb27SDimitry Andric   if (RC)
13506c3fb27SDimitry Andric     RC->Profile(ID, C, /*Canonical=*/true);
13606c3fb27SDimitry Andric   ID.AddInteger(size());
13706c3fb27SDimitry Andric   for (NamedDecl *D : *this) {
13806c3fb27SDimitry Andric     if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
13906c3fb27SDimitry Andric       ID.AddInteger(0);
14006c3fb27SDimitry Andric       ID.AddBoolean(NTTP->isParameterPack());
14106c3fb27SDimitry Andric       NTTP->getType().getCanonicalType().Profile(ID);
14206c3fb27SDimitry Andric       ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
14306c3fb27SDimitry Andric       if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
14406c3fb27SDimitry Andric         E->Profile(ID, C, /*Canonical=*/true);
14506c3fb27SDimitry Andric       continue;
14606c3fb27SDimitry Andric     }
14706c3fb27SDimitry Andric     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
14806c3fb27SDimitry Andric       ID.AddInteger(1);
14906c3fb27SDimitry Andric       ID.AddBoolean(TTP->isParameterPack());
15006c3fb27SDimitry Andric       ID.AddBoolean(TTP->hasTypeConstraint());
15106c3fb27SDimitry Andric       if (const TypeConstraint *TC = TTP->getTypeConstraint())
15206c3fb27SDimitry Andric         TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
15306c3fb27SDimitry Andric                                                         /*Canonical=*/true);
15406c3fb27SDimitry Andric       continue;
15506c3fb27SDimitry Andric     }
15606c3fb27SDimitry Andric     const auto *TTP = cast<TemplateTemplateParmDecl>(D);
15706c3fb27SDimitry Andric     ID.AddInteger(2);
15806c3fb27SDimitry Andric     ID.AddBoolean(TTP->isParameterPack());
15906c3fb27SDimitry Andric     TTP->getTemplateParameters()->Profile(ID, C);
16006c3fb27SDimitry Andric   }
16106c3fb27SDimitry Andric }
16206c3fb27SDimitry Andric 
1630b57cec5SDimitry Andric unsigned TemplateParameterList::getMinRequiredArguments() const {
1640b57cec5SDimitry Andric   unsigned NumRequiredArgs = 0;
1650b57cec5SDimitry Andric   for (const NamedDecl *P : asArray()) {
1660b57cec5SDimitry Andric     if (P->isTemplateParameterPack()) {
167bdd1243dSDimitry Andric       if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
168e8d8bef9SDimitry Andric         NumRequiredArgs += *Expansions;
1690b57cec5SDimitry Andric         continue;
1700b57cec5SDimitry Andric       }
1710b57cec5SDimitry Andric       break;
1720b57cec5SDimitry Andric     }
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
1750b57cec5SDimitry Andric       if (TTP->hasDefaultArgument())
1760b57cec5SDimitry Andric         break;
1770b57cec5SDimitry Andric     } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
1780b57cec5SDimitry Andric       if (NTTP->hasDefaultArgument())
1790b57cec5SDimitry Andric         break;
1800b57cec5SDimitry Andric     } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
1810b57cec5SDimitry Andric       break;
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric     ++NumRequiredArgs;
1840b57cec5SDimitry Andric   }
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   return NumRequiredArgs;
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric unsigned TemplateParameterList::getDepth() const {
1900b57cec5SDimitry Andric   if (size() == 0)
1910b57cec5SDimitry Andric     return 0;
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   const NamedDecl *FirstParm = getParam(0);
1940b57cec5SDimitry Andric   if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
1950b57cec5SDimitry Andric     return TTP->getDepth();
1960b57cec5SDimitry Andric   else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
1970b57cec5SDimitry Andric     return NTTP->getDepth();
1980b57cec5SDimitry Andric   else
1990b57cec5SDimitry Andric     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
2000b57cec5SDimitry Andric }
2010b57cec5SDimitry Andric 
202349cc55cSDimitry Andric static bool AdoptTemplateParameterList(TemplateParameterList *Params,
2030b57cec5SDimitry Andric                                        DeclContext *Owner) {
204349cc55cSDimitry Andric   bool Invalid = false;
2050b57cec5SDimitry Andric   for (NamedDecl *P : *Params) {
2060b57cec5SDimitry Andric     P->setDeclContext(Owner);
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric     if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
209349cc55cSDimitry Andric       if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
210349cc55cSDimitry Andric         Invalid = true;
211349cc55cSDimitry Andric 
212349cc55cSDimitry Andric     if (P->isInvalidDecl())
213349cc55cSDimitry Andric       Invalid = true;
2140b57cec5SDimitry Andric   }
215349cc55cSDimitry Andric   return Invalid;
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
218a7dea167SDimitry Andric void TemplateParameterList::
219a7dea167SDimitry Andric getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
220480093f4SDimitry Andric   if (HasConstrainedParameters)
22155e4f9d5SDimitry Andric     for (const NamedDecl *Param : *this) {
22255e4f9d5SDimitry Andric       if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
223480093f4SDimitry Andric         if (const auto *TC = TTP->getTypeConstraint())
224480093f4SDimitry Andric           AC.push_back(TC->getImmediatelyDeclaredConstraint());
22555e4f9d5SDimitry Andric       } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
22655e4f9d5SDimitry Andric         if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
22755e4f9d5SDimitry Andric           AC.push_back(E);
22855e4f9d5SDimitry Andric       }
22955e4f9d5SDimitry Andric     }
230a7dea167SDimitry Andric   if (HasRequiresClause)
231a7dea167SDimitry Andric     AC.push_back(getRequiresClause());
232a7dea167SDimitry Andric }
233a7dea167SDimitry Andric 
234a7dea167SDimitry Andric bool TemplateParameterList::hasAssociatedConstraints() const {
235480093f4SDimitry Andric   return HasRequiresClause || HasConstrainedParameters;
236a7dea167SDimitry Andric }
237a7dea167SDimitry Andric 
238fe6060f1SDimitry Andric bool TemplateParameterList::shouldIncludeTypeForArgument(
239349cc55cSDimitry Andric     const PrintingPolicy &Policy, const TemplateParameterList *TPL,
240349cc55cSDimitry Andric     unsigned Idx) {
241349cc55cSDimitry Andric   if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
242fe6060f1SDimitry Andric     return true;
243fe6060f1SDimitry Andric   const NamedDecl *TemplParam = TPL->getParam(Idx);
244fe6060f1SDimitry Andric   if (const auto *ParamValueDecl =
245fe6060f1SDimitry Andric           dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
246fe6060f1SDimitry Andric     if (ParamValueDecl->getType()->getContainedDeducedType())
247fe6060f1SDimitry Andric       return true;
248fe6060f1SDimitry Andric   return false;
249fe6060f1SDimitry Andric }
250fe6060f1SDimitry Andric 
2510b57cec5SDimitry Andric namespace clang {
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric void *allocateDefaultArgStorageChain(const ASTContext &C) {
2540b57cec5SDimitry Andric   return new (C) char[sizeof(void*) * 2];
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric } // namespace clang
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
260a7dea167SDimitry Andric // TemplateDecl Implementation
261a7dea167SDimitry Andric //===----------------------------------------------------------------------===//
262a7dea167SDimitry Andric 
263a7dea167SDimitry Andric TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
264a7dea167SDimitry Andric                            DeclarationName Name, TemplateParameterList *Params,
265a7dea167SDimitry Andric                            NamedDecl *Decl)
266a7dea167SDimitry Andric     : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
267a7dea167SDimitry Andric 
268a7dea167SDimitry Andric void TemplateDecl::anchor() {}
269a7dea167SDimitry Andric 
270a7dea167SDimitry Andric void TemplateDecl::
271a7dea167SDimitry Andric getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
272a7dea167SDimitry Andric   TemplateParams->getAssociatedConstraints(AC);
273480093f4SDimitry Andric   if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
274480093f4SDimitry Andric     if (const Expr *TRC = FD->getTrailingRequiresClause())
275480093f4SDimitry Andric       AC.push_back(TRC);
276a7dea167SDimitry Andric }
277a7dea167SDimitry Andric 
278a7dea167SDimitry Andric bool TemplateDecl::hasAssociatedConstraints() const {
279480093f4SDimitry Andric   if (TemplateParams->hasAssociatedConstraints())
280480093f4SDimitry Andric     return true;
281480093f4SDimitry Andric   if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
282480093f4SDimitry Andric     return FD->getTrailingRequiresClause();
283480093f4SDimitry Andric   return false;
284a7dea167SDimitry Andric }
285a7dea167SDimitry Andric 
286bdd1243dSDimitry Andric bool TemplateDecl::isTypeAlias() const {
287bdd1243dSDimitry Andric   switch (getKind()) {
288bdd1243dSDimitry Andric   case TemplateDecl::TypeAliasTemplate:
289bdd1243dSDimitry Andric   case TemplateDecl::BuiltinTemplate:
290bdd1243dSDimitry Andric     return true;
291bdd1243dSDimitry Andric   default:
292bdd1243dSDimitry Andric     return false;
293bdd1243dSDimitry Andric   };
294bdd1243dSDimitry Andric }
295bdd1243dSDimitry Andric 
296a7dea167SDimitry Andric //===----------------------------------------------------------------------===//
2970b57cec5SDimitry Andric // RedeclarableTemplateDecl Implementation
2980b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric void RedeclarableTemplateDecl::anchor() {}
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
3030b57cec5SDimitry Andric   if (Common)
3040b57cec5SDimitry Andric     return Common;
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   // Walk the previous-declaration chain until we either find a declaration
3070b57cec5SDimitry Andric   // with a common pointer or we run out of previous declarations.
3080b57cec5SDimitry Andric   SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
3090b57cec5SDimitry Andric   for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
3100b57cec5SDimitry Andric        Prev = Prev->getPreviousDecl()) {
3110b57cec5SDimitry Andric     if (Prev->Common) {
3120b57cec5SDimitry Andric       Common = Prev->Common;
3130b57cec5SDimitry Andric       break;
3140b57cec5SDimitry Andric     }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric     PrevDecls.push_back(Prev);
3170b57cec5SDimitry Andric   }
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric   // If we never found a common pointer, allocate one now.
3200b57cec5SDimitry Andric   if (!Common) {
3210b57cec5SDimitry Andric     // FIXME: If any of the declarations is from an AST file, we probably
3220b57cec5SDimitry Andric     // need an update record to add the common data.
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric     Common = newCommon(getASTContext());
3250b57cec5SDimitry Andric   }
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   // Update any previous declarations we saw with the common pointer.
3280b57cec5SDimitry Andric   for (const RedeclarableTemplateDecl *Prev : PrevDecls)
3290b57cec5SDimitry Andric     Prev->Common = Common;
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric   return Common;
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
3350b57cec5SDimitry Andric   // Grab the most recent declaration to ensure we've loaded any lazy
3360b57cec5SDimitry Andric   // redeclarations of this template.
3370b57cec5SDimitry Andric   CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
3380b57cec5SDimitry Andric   if (CommonBasePtr->LazySpecializations) {
3390b57cec5SDimitry Andric     ASTContext &Context = getASTContext();
340*0fca6ea1SDimitry Andric     GlobalDeclID *Specs = CommonBasePtr->LazySpecializations;
3410b57cec5SDimitry Andric     CommonBasePtr->LazySpecializations = nullptr;
342*0fca6ea1SDimitry Andric     unsigned SpecSize = (*Specs++).getRawValue();
343*0fca6ea1SDimitry Andric     for (unsigned I = 0; I != SpecSize; ++I)
3440b57cec5SDimitry Andric       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
3450b57cec5SDimitry Andric   }
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric 
348480093f4SDimitry Andric template<class EntryType, typename... ProfileArguments>
3490b57cec5SDimitry Andric typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
3500b57cec5SDimitry Andric RedeclarableTemplateDecl::findSpecializationImpl(
351480093f4SDimitry Andric     llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
352480093f4SDimitry Andric     ProfileArguments&&... ProfileArgs) {
3530b57cec5SDimitry Andric   using SETraits = SpecEntryTraits<EntryType>;
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric   llvm::FoldingSetNodeID ID;
356480093f4SDimitry Andric   EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
357480093f4SDimitry Andric                      getASTContext());
3580b57cec5SDimitry Andric   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
3590b57cec5SDimitry Andric   return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric 
3620b57cec5SDimitry Andric template<class Derived, class EntryType>
3630b57cec5SDimitry Andric void RedeclarableTemplateDecl::addSpecializationImpl(
3640b57cec5SDimitry Andric     llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
3650b57cec5SDimitry Andric     void *InsertPos) {
3660b57cec5SDimitry Andric   using SETraits = SpecEntryTraits<EntryType>;
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric   if (InsertPos) {
3690b57cec5SDimitry Andric #ifndef NDEBUG
3700b57cec5SDimitry Andric     void *CorrectInsertPos;
3710b57cec5SDimitry Andric     assert(!findSpecializationImpl(Specializations,
372480093f4SDimitry Andric                                    CorrectInsertPos,
373480093f4SDimitry Andric                                    SETraits::getTemplateArgs(Entry)) &&
3740b57cec5SDimitry Andric            InsertPos == CorrectInsertPos &&
3750b57cec5SDimitry Andric            "given incorrect InsertPos for specialization");
3760b57cec5SDimitry Andric #endif
3770b57cec5SDimitry Andric     Specializations.InsertNode(Entry, InsertPos);
3780b57cec5SDimitry Andric   } else {
3790b57cec5SDimitry Andric     EntryType *Existing = Specializations.GetOrInsertNode(Entry);
3800b57cec5SDimitry Andric     (void)Existing;
3810b57cec5SDimitry Andric     assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
3820b57cec5SDimitry Andric            "non-canonical specialization?");
3830b57cec5SDimitry Andric   }
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric   if (ASTMutationListener *L = getASTMutationListener())
3860b57cec5SDimitry Andric     L->AddedCXXTemplateSpecialization(cast<Derived>(this),
3870b57cec5SDimitry Andric                                       SETraits::getDecl(Entry));
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric 
390bdd1243dSDimitry Andric ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
391bdd1243dSDimitry Andric   TemplateParameterList *Params = getTemplateParameters();
392bdd1243dSDimitry Andric   auto *CommonPtr = getCommonPtr();
393bdd1243dSDimitry Andric   if (!CommonPtr->InjectedArgs) {
394bdd1243dSDimitry Andric     auto &Context = getASTContext();
395bdd1243dSDimitry Andric     SmallVector<TemplateArgument, 16> TemplateArgs;
396bdd1243dSDimitry Andric     Context.getInjectedTemplateArgs(Params, TemplateArgs);
397bdd1243dSDimitry Andric     CommonPtr->InjectedArgs =
398bdd1243dSDimitry Andric         new (Context) TemplateArgument[TemplateArgs.size()];
399bdd1243dSDimitry Andric     std::copy(TemplateArgs.begin(), TemplateArgs.end(),
400bdd1243dSDimitry Andric               CommonPtr->InjectedArgs);
401bdd1243dSDimitry Andric   }
402bdd1243dSDimitry Andric 
403bdd1243dSDimitry Andric   return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
404bdd1243dSDimitry Andric }
405bdd1243dSDimitry Andric 
4060b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4070b57cec5SDimitry Andric // FunctionTemplateDecl Implementation
4080b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4090b57cec5SDimitry Andric 
410349cc55cSDimitry Andric FunctionTemplateDecl *
411349cc55cSDimitry Andric FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
4120b57cec5SDimitry Andric                              DeclarationName Name,
413349cc55cSDimitry Andric                              TemplateParameterList *Params, NamedDecl *Decl) {
414349cc55cSDimitry Andric   bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
415349cc55cSDimitry Andric   auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
416349cc55cSDimitry Andric   if (Invalid)
417349cc55cSDimitry Andric     TD->setInvalidDecl();
418349cc55cSDimitry Andric   return TD;
4190b57cec5SDimitry Andric }
4200b57cec5SDimitry Andric 
421*0fca6ea1SDimitry Andric FunctionTemplateDecl *
422*0fca6ea1SDimitry Andric FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
4230b57cec5SDimitry Andric   return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
4240b57cec5SDimitry Andric                                           DeclarationName(), nullptr, nullptr);
4250b57cec5SDimitry Andric }
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric RedeclarableTemplateDecl::CommonBase *
4280b57cec5SDimitry Andric FunctionTemplateDecl::newCommon(ASTContext &C) const {
4290b57cec5SDimitry Andric   auto *CommonPtr = new (C) Common;
4300b57cec5SDimitry Andric   C.addDestruction(CommonPtr);
4310b57cec5SDimitry Andric   return CommonPtr;
4320b57cec5SDimitry Andric }
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric void FunctionTemplateDecl::LoadLazySpecializations() const {
4350b57cec5SDimitry Andric   loadLazySpecializationsImpl();
4360b57cec5SDimitry Andric }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
4390b57cec5SDimitry Andric FunctionTemplateDecl::getSpecializations() const {
4400b57cec5SDimitry Andric   LoadLazySpecializations();
4410b57cec5SDimitry Andric   return getCommonPtr()->Specializations;
4420b57cec5SDimitry Andric }
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric FunctionDecl *
4450b57cec5SDimitry Andric FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
4460b57cec5SDimitry Andric                                          void *&InsertPos) {
447480093f4SDimitry Andric   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
4480b57cec5SDimitry Andric }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric void FunctionTemplateDecl::addSpecialization(
4510b57cec5SDimitry Andric       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
4520b57cec5SDimitry Andric   addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
4530b57cec5SDimitry Andric                                               InsertPos);
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
4570b57cec5SDimitry Andric   using Base = RedeclarableTemplateDecl;
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   // If we haven't created a common pointer yet, then it can just be created
4600b57cec5SDimitry Andric   // with the usual method.
4610b57cec5SDimitry Andric   if (!Base::Common)
4620b57cec5SDimitry Andric     return;
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric   Common *ThisCommon = static_cast<Common *>(Base::Common);
4650b57cec5SDimitry Andric   Common *PrevCommon = nullptr;
4660b57cec5SDimitry Andric   SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
4670b57cec5SDimitry Andric   for (; Prev; Prev = Prev->getPreviousDecl()) {
4680b57cec5SDimitry Andric     if (Prev->Base::Common) {
4690b57cec5SDimitry Andric       PrevCommon = static_cast<Common *>(Prev->Base::Common);
4700b57cec5SDimitry Andric       break;
4710b57cec5SDimitry Andric     }
4720b57cec5SDimitry Andric     PreviousDecls.push_back(Prev);
4730b57cec5SDimitry Andric   }
4740b57cec5SDimitry Andric 
4750b57cec5SDimitry Andric   // If the previous redecl chain hasn't created a common pointer yet, then just
4760b57cec5SDimitry Andric   // use this common pointer.
4770b57cec5SDimitry Andric   if (!PrevCommon) {
4780b57cec5SDimitry Andric     for (auto *D : PreviousDecls)
4790b57cec5SDimitry Andric       D->Base::Common = ThisCommon;
4800b57cec5SDimitry Andric     return;
4810b57cec5SDimitry Andric   }
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric   // Ensure we don't leak any important state.
4840b57cec5SDimitry Andric   assert(ThisCommon->Specializations.size() == 0 &&
4850b57cec5SDimitry Andric          "Can't merge incompatible declarations!");
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric   Base::Common = PrevCommon;
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4910b57cec5SDimitry Andric // ClassTemplateDecl Implementation
4920b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
4930b57cec5SDimitry Andric 
494349cc55cSDimitry Andric ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
4950b57cec5SDimitry Andric                                              SourceLocation L,
4960b57cec5SDimitry Andric                                              DeclarationName Name,
4970b57cec5SDimitry Andric                                              TemplateParameterList *Params,
498a7dea167SDimitry Andric                                              NamedDecl *Decl) {
499349cc55cSDimitry Andric   bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
500349cc55cSDimitry Andric   auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
501349cc55cSDimitry Andric   if (Invalid)
502349cc55cSDimitry Andric     TD->setInvalidDecl();
503349cc55cSDimitry Andric   return TD;
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric 
5060b57cec5SDimitry Andric ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
507*0fca6ea1SDimitry Andric                                                          GlobalDeclID ID) {
5080b57cec5SDimitry Andric   return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
5090b57cec5SDimitry Andric                                        DeclarationName(), nullptr, nullptr);
5100b57cec5SDimitry Andric }
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric void ClassTemplateDecl::LoadLazySpecializations() const {
5130b57cec5SDimitry Andric   loadLazySpecializationsImpl();
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
5170b57cec5SDimitry Andric ClassTemplateDecl::getSpecializations() const {
5180b57cec5SDimitry Andric   LoadLazySpecializations();
5190b57cec5SDimitry Andric   return getCommonPtr()->Specializations;
5200b57cec5SDimitry Andric }
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
523e8d8bef9SDimitry Andric ClassTemplateDecl::getPartialSpecializations() const {
5240b57cec5SDimitry Andric   LoadLazySpecializations();
5250b57cec5SDimitry Andric   return getCommonPtr()->PartialSpecializations;
5260b57cec5SDimitry Andric }
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric RedeclarableTemplateDecl::CommonBase *
5290b57cec5SDimitry Andric ClassTemplateDecl::newCommon(ASTContext &C) const {
5300b57cec5SDimitry Andric   auto *CommonPtr = new (C) Common;
5310b57cec5SDimitry Andric   C.addDestruction(CommonPtr);
5320b57cec5SDimitry Andric   return CommonPtr;
5330b57cec5SDimitry Andric }
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric ClassTemplateSpecializationDecl *
5360b57cec5SDimitry Andric ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
5370b57cec5SDimitry Andric                                       void *&InsertPos) {
538480093f4SDimitry Andric   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
5420b57cec5SDimitry Andric                                           void *InsertPos) {
5430b57cec5SDimitry Andric   addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
5440b57cec5SDimitry Andric }
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *
547480093f4SDimitry Andric ClassTemplateDecl::findPartialSpecialization(
548480093f4SDimitry Andric     ArrayRef<TemplateArgument> Args,
549480093f4SDimitry Andric     TemplateParameterList *TPL, void *&InsertPos) {
550480093f4SDimitry Andric   return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
551480093f4SDimitry Andric                                 TPL);
552480093f4SDimitry Andric }
553480093f4SDimitry Andric 
55406c3fb27SDimitry Andric void ClassTemplatePartialSpecializationDecl::Profile(
55506c3fb27SDimitry Andric     llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
55606c3fb27SDimitry Andric     TemplateParameterList *TPL, const ASTContext &Context) {
557480093f4SDimitry Andric   ID.AddInteger(TemplateArgs.size());
558480093f4SDimitry Andric   for (const TemplateArgument &TemplateArg : TemplateArgs)
559480093f4SDimitry Andric     TemplateArg.Profile(ID, Context);
56006c3fb27SDimitry Andric   TPL->Profile(ID, Context);
5610b57cec5SDimitry Andric }
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric void ClassTemplateDecl::AddPartialSpecialization(
5640b57cec5SDimitry Andric                                       ClassTemplatePartialSpecializationDecl *D,
5650b57cec5SDimitry Andric                                       void *InsertPos) {
5660b57cec5SDimitry Andric   if (InsertPos)
5670b57cec5SDimitry Andric     getPartialSpecializations().InsertNode(D, InsertPos);
5680b57cec5SDimitry Andric   else {
5690b57cec5SDimitry Andric     ClassTemplatePartialSpecializationDecl *Existing
5700b57cec5SDimitry Andric       = getPartialSpecializations().GetOrInsertNode(D);
5710b57cec5SDimitry Andric     (void)Existing;
5720b57cec5SDimitry Andric     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
5730b57cec5SDimitry Andric   }
5740b57cec5SDimitry Andric 
5750b57cec5SDimitry Andric   if (ASTMutationListener *L = getASTMutationListener())
5760b57cec5SDimitry Andric     L->AddedCXXTemplateSpecialization(this, D);
5770b57cec5SDimitry Andric }
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric void ClassTemplateDecl::getPartialSpecializations(
580e8d8bef9SDimitry Andric     SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {
5810b57cec5SDimitry Andric   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
5820b57cec5SDimitry Andric     = getPartialSpecializations();
5830b57cec5SDimitry Andric   PS.clear();
5840b57cec5SDimitry Andric   PS.reserve(PartialSpecs.size());
5850b57cec5SDimitry Andric   for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
5860b57cec5SDimitry Andric     PS.push_back(P.getMostRecentDecl());
5870b57cec5SDimitry Andric }
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *
5900b57cec5SDimitry Andric ClassTemplateDecl::findPartialSpecialization(QualType T) {
5910b57cec5SDimitry Andric   ASTContext &Context = getASTContext();
5920b57cec5SDimitry Andric   for (ClassTemplatePartialSpecializationDecl &P :
5930b57cec5SDimitry Andric        getPartialSpecializations()) {
5940b57cec5SDimitry Andric     if (Context.hasSameType(P.getInjectedSpecializationType(), T))
5950b57cec5SDimitry Andric       return P.getMostRecentDecl();
5960b57cec5SDimitry Andric   }
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric   return nullptr;
5990b57cec5SDimitry Andric }
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *
6020b57cec5SDimitry Andric ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
6030b57cec5SDimitry Andric                                     ClassTemplatePartialSpecializationDecl *D) {
6040b57cec5SDimitry Andric   Decl *DCanon = D->getCanonicalDecl();
6050b57cec5SDimitry Andric   for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
6060b57cec5SDimitry Andric     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
6070b57cec5SDimitry Andric       return P.getMostRecentDecl();
6080b57cec5SDimitry Andric   }
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric   return nullptr;
6110b57cec5SDimitry Andric }
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric QualType
6140b57cec5SDimitry Andric ClassTemplateDecl::getInjectedClassNameSpecialization() {
6150b57cec5SDimitry Andric   Common *CommonPtr = getCommonPtr();
6160b57cec5SDimitry Andric   if (!CommonPtr->InjectedClassNameType.isNull())
6170b57cec5SDimitry Andric     return CommonPtr->InjectedClassNameType;
6180b57cec5SDimitry Andric 
6190b57cec5SDimitry Andric   // C++0x [temp.dep.type]p2:
6200b57cec5SDimitry Andric   //  The template argument list of a primary template is a template argument
6210b57cec5SDimitry Andric   //  list in which the nth template argument has the value of the nth template
6220b57cec5SDimitry Andric   //  parameter of the class template. If the nth template parameter is a
6230b57cec5SDimitry Andric   //  template parameter pack (14.5.3), the nth template argument is a pack
6240b57cec5SDimitry Andric   //  expansion (14.5.3) whose pattern is the name of the template parameter
6250b57cec5SDimitry Andric   //  pack.
6260b57cec5SDimitry Andric   ASTContext &Context = getASTContext();
6270b57cec5SDimitry Andric   TemplateParameterList *Params = getTemplateParameters();
6280b57cec5SDimitry Andric   SmallVector<TemplateArgument, 16> TemplateArgs;
6290b57cec5SDimitry Andric   Context.getInjectedTemplateArgs(Params, TemplateArgs);
630*0fca6ea1SDimitry Andric   TemplateName Name = Context.getQualifiedTemplateName(
631*0fca6ea1SDimitry Andric       /*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));
632*0fca6ea1SDimitry Andric   CommonPtr->InjectedClassNameType =
633*0fca6ea1SDimitry Andric       Context.getTemplateSpecializationType(Name, TemplateArgs);
6340b57cec5SDimitry Andric   return CommonPtr->InjectedClassNameType;
6350b57cec5SDimitry Andric }
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6380b57cec5SDimitry Andric // TemplateTypeParm Allocation/Deallocation Method Implementations
6390b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6400b57cec5SDimitry Andric 
641bdd1243dSDimitry Andric TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
642bdd1243dSDimitry Andric     const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
643bdd1243dSDimitry Andric     SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
644bdd1243dSDimitry Andric     bool Typename, bool ParameterPack, bool HasTypeConstraint,
645bdd1243dSDimitry Andric     std::optional<unsigned> NumExpanded) {
6460b57cec5SDimitry Andric   auto *TTPDecl =
647480093f4SDimitry Andric       new (C, DC,
648480093f4SDimitry Andric            additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
649480093f4SDimitry Andric       TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
650480093f4SDimitry Andric                            HasTypeConstraint, NumExpanded);
6510b57cec5SDimitry Andric   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
6520b57cec5SDimitry Andric   TTPDecl->setTypeForDecl(TTPType.getTypePtr());
6530b57cec5SDimitry Andric   return TTPDecl;
6540b57cec5SDimitry Andric }
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric TemplateTypeParmDecl *
657*0fca6ea1SDimitry Andric TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) {
658bdd1243dSDimitry Andric   return new (C, ID)
659bdd1243dSDimitry Andric       TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
660bdd1243dSDimitry Andric                            false, false, std::nullopt);
661480093f4SDimitry Andric }
662480093f4SDimitry Andric 
663480093f4SDimitry Andric TemplateTypeParmDecl *
664*0fca6ea1SDimitry Andric TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID,
665480093f4SDimitry Andric                                          bool HasTypeConstraint) {
666480093f4SDimitry Andric   return new (C, ID,
667480093f4SDimitry Andric               additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
668bdd1243dSDimitry Andric       TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
669bdd1243dSDimitry Andric                            false, HasTypeConstraint, std::nullopt);
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
673*0fca6ea1SDimitry Andric   return hasDefaultArgument() ? getDefaultArgument().getLocation()
6740b57cec5SDimitry Andric                               : SourceLocation();
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric 
6770b57cec5SDimitry Andric SourceRange TemplateTypeParmDecl::getSourceRange() const {
6780b57cec5SDimitry Andric   if (hasDefaultArgument() && !defaultArgumentWasInherited())
6790b57cec5SDimitry Andric     return SourceRange(getBeginLoc(),
680*0fca6ea1SDimitry Andric                        getDefaultArgument().getSourceRange().getEnd());
681a7dea167SDimitry Andric   // TypeDecl::getSourceRange returns a range containing name location, which is
682a7dea167SDimitry Andric   // wrong for unnamed template parameters. e.g:
683a7dea167SDimitry Andric   // it will return <[[typename>]] instead of <[[typename]]>
684*0fca6ea1SDimitry Andric   if (getDeclName().isEmpty())
685a7dea167SDimitry Andric     return SourceRange(getBeginLoc());
6860b57cec5SDimitry Andric   return TypeDecl::getSourceRange();
6870b57cec5SDimitry Andric }
6880b57cec5SDimitry Andric 
689*0fca6ea1SDimitry Andric void TemplateTypeParmDecl::setDefaultArgument(
690*0fca6ea1SDimitry Andric     const ASTContext &C, const TemplateArgumentLoc &DefArg) {
691*0fca6ea1SDimitry Andric   if (DefArg.getArgument().isNull())
692*0fca6ea1SDimitry Andric     DefaultArgument.set(nullptr);
693*0fca6ea1SDimitry Andric   else
694*0fca6ea1SDimitry Andric     DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
695*0fca6ea1SDimitry Andric }
696*0fca6ea1SDimitry Andric 
6970b57cec5SDimitry Andric unsigned TemplateTypeParmDecl::getDepth() const {
698a7dea167SDimitry Andric   return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
6990b57cec5SDimitry Andric }
7000b57cec5SDimitry Andric 
7010b57cec5SDimitry Andric unsigned TemplateTypeParmDecl::getIndex() const {
702a7dea167SDimitry Andric   return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
7030b57cec5SDimitry Andric }
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric bool TemplateTypeParmDecl::isParameterPack() const {
706a7dea167SDimitry Andric   return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
7070b57cec5SDimitry Andric }
7080b57cec5SDimitry Andric 
7095f757f3fSDimitry Andric void TemplateTypeParmDecl::setTypeConstraint(
7105f757f3fSDimitry Andric     ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {
711480093f4SDimitry Andric   assert(HasTypeConstraint &&
712480093f4SDimitry Andric          "HasTypeConstraint=true must be passed at construction in order to "
713480093f4SDimitry Andric          "call setTypeConstraint");
714480093f4SDimitry Andric   assert(!TypeConstraintInitialized &&
715480093f4SDimitry Andric          "TypeConstraint was already initialized!");
7165f757f3fSDimitry Andric   new (getTrailingObjects<TypeConstraint>())
7175f757f3fSDimitry Andric       TypeConstraint(Loc, ImmediatelyDeclaredConstraint);
718480093f4SDimitry Andric   TypeConstraintInitialized = true;
719480093f4SDimitry Andric }
720480093f4SDimitry Andric 
7210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7220b57cec5SDimitry Andric // NonTypeTemplateParmDecl Method Implementations
7230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
7260b57cec5SDimitry Andric     DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
727*0fca6ea1SDimitry Andric     unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
7280b57cec5SDimitry Andric     ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
7290b57cec5SDimitry Andric     : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
7300b57cec5SDimitry Andric       TemplateParmPosition(D, P), ParameterPack(true),
7310b57cec5SDimitry Andric       ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
7320b57cec5SDimitry Andric   if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
7330b57cec5SDimitry Andric     auto TypesAndInfos =
7340b57cec5SDimitry Andric         getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
7350b57cec5SDimitry Andric     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
7360b57cec5SDimitry Andric       new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
7370b57cec5SDimitry Andric       TypesAndInfos[I].second = ExpandedTInfos[I];
7380b57cec5SDimitry Andric     }
7390b57cec5SDimitry Andric   }
7400b57cec5SDimitry Andric }
7410b57cec5SDimitry Andric 
742*0fca6ea1SDimitry Andric NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
743*0fca6ea1SDimitry Andric     const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
744*0fca6ea1SDimitry Andric     SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
745*0fca6ea1SDimitry Andric     QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
74655e4f9d5SDimitry Andric   AutoType *AT =
7475ffd83dbSDimitry Andric       C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
74855e4f9d5SDimitry Andric   return new (C, DC,
74955e4f9d5SDimitry Andric               additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
75055e4f9d5SDimitry Andric                                     Expr *>(0,
75155e4f9d5SDimitry Andric                                             AT && AT->isConstrained() ? 1 : 0))
75255e4f9d5SDimitry Andric       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
75355e4f9d5SDimitry Andric                               TInfo);
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
7570b57cec5SDimitry Andric     const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
758*0fca6ea1SDimitry Andric     SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
7590b57cec5SDimitry Andric     QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
7600b57cec5SDimitry Andric     ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
76155e4f9d5SDimitry Andric   AutoType *AT = TInfo->getType()->getContainedAutoType();
7620b57cec5SDimitry Andric   return new (C, DC,
76355e4f9d5SDimitry Andric               additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
76455e4f9d5SDimitry Andric                                     Expr *>(
76555e4f9d5SDimitry Andric                   ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
7660b57cec5SDimitry Andric       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
7670b57cec5SDimitry Andric                               ExpandedTypes, ExpandedTInfos);
7680b57cec5SDimitry Andric }
7690b57cec5SDimitry Andric 
7700b57cec5SDimitry Andric NonTypeTemplateParmDecl *
771*0fca6ea1SDimitry Andric NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
77255e4f9d5SDimitry Andric                                             bool HasTypeConstraint) {
77355e4f9d5SDimitry Andric   return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
77455e4f9d5SDimitry Andric                                                      TypeSourceInfo *>,
77555e4f9d5SDimitry Andric                                            Expr *>(0,
77655e4f9d5SDimitry Andric                                                    HasTypeConstraint ? 1 : 0))
77755e4f9d5SDimitry Andric           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
77855e4f9d5SDimitry Andric                                   0, 0, nullptr, QualType(), false, nullptr);
7790b57cec5SDimitry Andric }
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric NonTypeTemplateParmDecl *
782*0fca6ea1SDimitry Andric NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
78355e4f9d5SDimitry Andric                                             unsigned NumExpandedTypes,
78455e4f9d5SDimitry Andric                                             bool HasTypeConstraint) {
7850b57cec5SDimitry Andric   auto *NTTP =
786bdd1243dSDimitry Andric       new (C, ID,
787bdd1243dSDimitry Andric            additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
78855e4f9d5SDimitry Andric                NumExpandedTypes, HasTypeConstraint ? 1 : 0))
7890b57cec5SDimitry Andric           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
790bdd1243dSDimitry Andric                                   0, 0, nullptr, QualType(), nullptr,
791bdd1243dSDimitry Andric                                   std::nullopt, std::nullopt);
7920b57cec5SDimitry Andric   NTTP->NumExpandedTypes = NumExpandedTypes;
7930b57cec5SDimitry Andric   return NTTP;
7940b57cec5SDimitry Andric }
7950b57cec5SDimitry Andric 
7960b57cec5SDimitry Andric SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
7970b57cec5SDimitry Andric   if (hasDefaultArgument() && !defaultArgumentWasInherited())
7980b57cec5SDimitry Andric     return SourceRange(getOuterLocStart(),
799*0fca6ea1SDimitry Andric                        getDefaultArgument().getSourceRange().getEnd());
8000b57cec5SDimitry Andric   return DeclaratorDecl::getSourceRange();
8010b57cec5SDimitry Andric }
8020b57cec5SDimitry Andric 
8030b57cec5SDimitry Andric SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
804*0fca6ea1SDimitry Andric   return hasDefaultArgument() ? getDefaultArgument().getSourceRange().getBegin()
8050b57cec5SDimitry Andric                               : SourceLocation();
8060b57cec5SDimitry Andric }
8070b57cec5SDimitry Andric 
808*0fca6ea1SDimitry Andric void NonTypeTemplateParmDecl::setDefaultArgument(
809*0fca6ea1SDimitry Andric     const ASTContext &C, const TemplateArgumentLoc &DefArg) {
810*0fca6ea1SDimitry Andric   if (DefArg.getArgument().isNull())
811*0fca6ea1SDimitry Andric     DefaultArgument.set(nullptr);
812*0fca6ea1SDimitry Andric   else
813*0fca6ea1SDimitry Andric     DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
814*0fca6ea1SDimitry Andric }
815*0fca6ea1SDimitry Andric 
8160b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8170b57cec5SDimitry Andric // TemplateTemplateParmDecl Method Implementations
8180b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8190b57cec5SDimitry Andric 
8200b57cec5SDimitry Andric void TemplateTemplateParmDecl::anchor() {}
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric TemplateTemplateParmDecl::TemplateTemplateParmDecl(
8230b57cec5SDimitry Andric     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
824*0fca6ea1SDimitry Andric     IdentifierInfo *Id, bool Typename, TemplateParameterList *Params,
8250b57cec5SDimitry Andric     ArrayRef<TemplateParameterList *> Expansions)
8260b57cec5SDimitry Andric     : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
827*0fca6ea1SDimitry Andric       TemplateParmPosition(D, P), Typename(Typename), ParameterPack(true),
8280b57cec5SDimitry Andric       ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
8290b57cec5SDimitry Andric   if (!Expansions.empty())
8300b57cec5SDimitry Andric     std::uninitialized_copy(Expansions.begin(), Expansions.end(),
8310b57cec5SDimitry Andric                             getTrailingObjects<TemplateParameterList *>());
8320b57cec5SDimitry Andric }
8330b57cec5SDimitry Andric 
8340b57cec5SDimitry Andric TemplateTemplateParmDecl *
8350b57cec5SDimitry Andric TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
8360b57cec5SDimitry Andric                                  SourceLocation L, unsigned D, unsigned P,
8370b57cec5SDimitry Andric                                  bool ParameterPack, IdentifierInfo *Id,
838*0fca6ea1SDimitry Andric                                  bool Typename, TemplateParameterList *Params) {
8390b57cec5SDimitry Andric   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
840*0fca6ea1SDimitry Andric                                               Typename, Params);
8410b57cec5SDimitry Andric }
8420b57cec5SDimitry Andric 
8430b57cec5SDimitry Andric TemplateTemplateParmDecl *
8440b57cec5SDimitry Andric TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
8450b57cec5SDimitry Andric                                  SourceLocation L, unsigned D, unsigned P,
846*0fca6ea1SDimitry Andric                                  IdentifierInfo *Id, bool Typename,
8470b57cec5SDimitry Andric                                  TemplateParameterList *Params,
8480b57cec5SDimitry Andric                                  ArrayRef<TemplateParameterList *> Expansions) {
8490b57cec5SDimitry Andric   return new (C, DC,
8500b57cec5SDimitry Andric               additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
851*0fca6ea1SDimitry Andric       TemplateTemplateParmDecl(DC, L, D, P, Id, Typename, Params, Expansions);
8520b57cec5SDimitry Andric }
8530b57cec5SDimitry Andric 
8540b57cec5SDimitry Andric TemplateTemplateParmDecl *
855*0fca6ea1SDimitry Andric TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
8560b57cec5SDimitry Andric   return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
857*0fca6ea1SDimitry Andric                                               false, nullptr, false, nullptr);
8580b57cec5SDimitry Andric }
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric TemplateTemplateParmDecl *
861*0fca6ea1SDimitry Andric TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
8620b57cec5SDimitry Andric                                              unsigned NumExpansions) {
8630b57cec5SDimitry Andric   auto *TTP =
8640b57cec5SDimitry Andric       new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
8650b57cec5SDimitry Andric           TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
866*0fca6ea1SDimitry Andric                                    false, nullptr, std::nullopt);
8670b57cec5SDimitry Andric   TTP->NumExpandedParams = NumExpansions;
8680b57cec5SDimitry Andric   return TTP;
8690b57cec5SDimitry Andric }
8700b57cec5SDimitry Andric 
8710b57cec5SDimitry Andric SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
8720b57cec5SDimitry Andric   return hasDefaultArgument() ? getDefaultArgument().getLocation()
8730b57cec5SDimitry Andric                               : SourceLocation();
8740b57cec5SDimitry Andric }
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric void TemplateTemplateParmDecl::setDefaultArgument(
8770b57cec5SDimitry Andric     const ASTContext &C, const TemplateArgumentLoc &DefArg) {
8780b57cec5SDimitry Andric   if (DefArg.getArgument().isNull())
8790b57cec5SDimitry Andric     DefaultArgument.set(nullptr);
8800b57cec5SDimitry Andric   else
8810b57cec5SDimitry Andric     DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
8820b57cec5SDimitry Andric }
8830b57cec5SDimitry Andric 
8840b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8850b57cec5SDimitry Andric // TemplateArgumentList Implementation
8860b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8870b57cec5SDimitry Andric TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
888*0fca6ea1SDimitry Andric     : NumArguments(Args.size()) {
8890b57cec5SDimitry Andric   std::uninitialized_copy(Args.begin(), Args.end(),
8900b57cec5SDimitry Andric                           getTrailingObjects<TemplateArgument>());
8910b57cec5SDimitry Andric }
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric TemplateArgumentList *
8940b57cec5SDimitry Andric TemplateArgumentList::CreateCopy(ASTContext &Context,
8950b57cec5SDimitry Andric                                  ArrayRef<TemplateArgument> Args) {
8960b57cec5SDimitry Andric   void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
8970b57cec5SDimitry Andric   return new (Mem) TemplateArgumentList(Args);
8980b57cec5SDimitry Andric }
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
9010b57cec5SDimitry Andric     ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
902*0fca6ea1SDimitry Andric     TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,
9030b57cec5SDimitry Andric     const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
9040b57cec5SDimitry Andric     MemberSpecializationInfo *MSInfo) {
9050b57cec5SDimitry Andric   const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
9060b57cec5SDimitry Andric   if (TemplateArgsAsWritten)
9070b57cec5SDimitry Andric     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
9080b57cec5SDimitry Andric                                                         *TemplateArgsAsWritten);
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric   void *Mem =
9110b57cec5SDimitry Andric       C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
9120b57cec5SDimitry Andric   return new (Mem) FunctionTemplateSpecializationInfo(
9130b57cec5SDimitry Andric       FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
9140b57cec5SDimitry Andric }
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9170b57cec5SDimitry Andric // ClassTemplateSpecializationDecl Implementation
9180b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric ClassTemplateSpecializationDecl::
9210b57cec5SDimitry Andric ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
9220b57cec5SDimitry Andric                                 DeclContext *DC, SourceLocation StartLoc,
9230b57cec5SDimitry Andric                                 SourceLocation IdLoc,
9240b57cec5SDimitry Andric                                 ClassTemplateDecl *SpecializedTemplate,
9250b57cec5SDimitry Andric                                 ArrayRef<TemplateArgument> Args,
9260b57cec5SDimitry Andric                                 ClassTemplateSpecializationDecl *PrevDecl)
9270b57cec5SDimitry Andric     : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
9280b57cec5SDimitry Andric                     SpecializedTemplate->getIdentifier(), PrevDecl),
9290b57cec5SDimitry Andric     SpecializedTemplate(SpecializedTemplate),
9300b57cec5SDimitry Andric     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
9310b57cec5SDimitry Andric     SpecializationKind(TSK_Undeclared) {
9320b57cec5SDimitry Andric }
9330b57cec5SDimitry Andric 
9340b57cec5SDimitry Andric ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
9350b57cec5SDimitry Andric                                                                  Kind DK)
9365f757f3fSDimitry Andric     : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),
9370b57cec5SDimitry Andric                     SourceLocation(), nullptr, nullptr),
9380b57cec5SDimitry Andric       SpecializationKind(TSK_Undeclared) {}
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric ClassTemplateSpecializationDecl *
9410b57cec5SDimitry Andric ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
9420b57cec5SDimitry Andric                                         DeclContext *DC,
9430b57cec5SDimitry Andric                                         SourceLocation StartLoc,
9440b57cec5SDimitry Andric                                         SourceLocation IdLoc,
9450b57cec5SDimitry Andric                                         ClassTemplateDecl *SpecializedTemplate,
9460b57cec5SDimitry Andric                                         ArrayRef<TemplateArgument> Args,
9470b57cec5SDimitry Andric                                    ClassTemplateSpecializationDecl *PrevDecl) {
9480b57cec5SDimitry Andric   auto *Result =
9490b57cec5SDimitry Andric       new (Context, DC) ClassTemplateSpecializationDecl(
9500b57cec5SDimitry Andric           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
9510b57cec5SDimitry Andric           SpecializedTemplate, Args, PrevDecl);
9520b57cec5SDimitry Andric   Result->setMayHaveOutOfDateDef(false);
9530b57cec5SDimitry Andric 
954bdd1243dSDimitry Andric   // If the template decl is incomplete, copy the external lexical storage from
955bdd1243dSDimitry Andric   // the base template. This allows instantiations of incomplete types to
956bdd1243dSDimitry Andric   // complete using the external AST if the template's declaration came from an
957bdd1243dSDimitry Andric   // external AST.
958bdd1243dSDimitry Andric   if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
959bdd1243dSDimitry Andric     Result->setHasExternalLexicalStorage(
960bdd1243dSDimitry Andric       SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
961bdd1243dSDimitry Andric 
9620b57cec5SDimitry Andric   Context.getTypeDeclType(Result, PrevDecl);
9630b57cec5SDimitry Andric   return Result;
9640b57cec5SDimitry Andric }
9650b57cec5SDimitry Andric 
9660b57cec5SDimitry Andric ClassTemplateSpecializationDecl *
9670b57cec5SDimitry Andric ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
968*0fca6ea1SDimitry Andric                                                     GlobalDeclID ID) {
9690b57cec5SDimitry Andric   auto *Result =
9700b57cec5SDimitry Andric     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
9710b57cec5SDimitry Andric   Result->setMayHaveOutOfDateDef(false);
9720b57cec5SDimitry Andric   return Result;
9730b57cec5SDimitry Andric }
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric void ClassTemplateSpecializationDecl::getNameForDiagnostic(
9760b57cec5SDimitry Andric     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
9770b57cec5SDimitry Andric   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric   const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
9800b57cec5SDimitry Andric   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
9810b57cec5SDimitry Andric           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
982e8d8bef9SDimitry Andric     printTemplateArgumentList(
983e8d8bef9SDimitry Andric         OS, ArgsAsWritten->arguments(), Policy,
984e8d8bef9SDimitry Andric         getSpecializedTemplate()->getTemplateParameters());
9850b57cec5SDimitry Andric   } else {
9860b57cec5SDimitry Andric     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
987e8d8bef9SDimitry Andric     printTemplateArgumentList(
988e8d8bef9SDimitry Andric         OS, TemplateArgs.asArray(), Policy,
989e8d8bef9SDimitry Andric         getSpecializedTemplate()->getTemplateParameters());
9900b57cec5SDimitry Andric   }
9910b57cec5SDimitry Andric }
9920b57cec5SDimitry Andric 
9930b57cec5SDimitry Andric ClassTemplateDecl *
9940b57cec5SDimitry Andric ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
9950b57cec5SDimitry Andric   if (const auto *PartialSpec =
9960b57cec5SDimitry Andric           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
9970b57cec5SDimitry Andric     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
9980b57cec5SDimitry Andric   return SpecializedTemplate.get<ClassTemplateDecl*>();
9990b57cec5SDimitry Andric }
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric SourceRange
10020b57cec5SDimitry Andric ClassTemplateSpecializationDecl::getSourceRange() const {
1003*0fca6ea1SDimitry Andric   switch (getSpecializationKind()) {
1004*0fca6ea1SDimitry Andric   case TSK_Undeclared:
1005*0fca6ea1SDimitry Andric   case TSK_ImplicitInstantiation: {
10060b57cec5SDimitry Andric     llvm::PointerUnion<ClassTemplateDecl *,
10070b57cec5SDimitry Andric                        ClassTemplatePartialSpecializationDecl *>
1008*0fca6ea1SDimitry Andric         Pattern = getSpecializedTemplateOrPartial();
1009*0fca6ea1SDimitry Andric     assert(!Pattern.isNull() &&
1010*0fca6ea1SDimitry Andric            "Class template specialization without pattern?");
1011*0fca6ea1SDimitry Andric     if (const auto *CTPSD =
1012*0fca6ea1SDimitry Andric             Pattern.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1013*0fca6ea1SDimitry Andric       return CTPSD->getSourceRange();
1014*0fca6ea1SDimitry Andric     return Pattern.get<ClassTemplateDecl *>()->getSourceRange();
10150b57cec5SDimitry Andric   }
1016*0fca6ea1SDimitry Andric   case TSK_ExplicitSpecialization: {
1017*0fca6ea1SDimitry Andric     SourceRange Range = CXXRecordDecl::getSourceRange();
1018*0fca6ea1SDimitry Andric     if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
1019*0fca6ea1SDimitry Andric         !isThisDeclarationADefinition() && Args)
1020*0fca6ea1SDimitry Andric       Range.setEnd(Args->getRAngleLoc());
1021*0fca6ea1SDimitry Andric     return Range;
1022*0fca6ea1SDimitry Andric   }
1023*0fca6ea1SDimitry Andric   case TSK_ExplicitInstantiationDeclaration:
1024*0fca6ea1SDimitry Andric   case TSK_ExplicitInstantiationDefinition: {
1025*0fca6ea1SDimitry Andric     SourceRange Range = CXXRecordDecl::getSourceRange();
1026*0fca6ea1SDimitry Andric     if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1027*0fca6ea1SDimitry Andric       Range.setBegin(ExternKW);
1028*0fca6ea1SDimitry Andric     else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1029*0fca6ea1SDimitry Andric              TemplateKW.isValid())
1030*0fca6ea1SDimitry Andric       Range.setBegin(TemplateKW);
1031*0fca6ea1SDimitry Andric     if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
1032*0fca6ea1SDimitry Andric       Range.setEnd(Args->getRAngleLoc());
1033*0fca6ea1SDimitry Andric     return Range;
1034*0fca6ea1SDimitry Andric   }
1035*0fca6ea1SDimitry Andric   }
1036*0fca6ea1SDimitry Andric   llvm_unreachable("unhandled template specialization kind");
1037*0fca6ea1SDimitry Andric }
1038*0fca6ea1SDimitry Andric 
1039*0fca6ea1SDimitry Andric void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
1040*0fca6ea1SDimitry Andric   auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1041*0fca6ea1SDimitry Andric   if (!Info) {
1042*0fca6ea1SDimitry Andric     // Don't allocate if the location is invalid.
1043*0fca6ea1SDimitry Andric     if (Loc.isInvalid())
1044*0fca6ea1SDimitry Andric       return;
1045*0fca6ea1SDimitry Andric     Info = new (getASTContext()) ExplicitInstantiationInfo;
1046*0fca6ea1SDimitry Andric     Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1047*0fca6ea1SDimitry Andric     ExplicitInfo = Info;
1048*0fca6ea1SDimitry Andric   }
1049*0fca6ea1SDimitry Andric   Info->ExternKeywordLoc = Loc;
1050*0fca6ea1SDimitry Andric }
1051*0fca6ea1SDimitry Andric 
1052*0fca6ea1SDimitry Andric void ClassTemplateSpecializationDecl::setTemplateKeywordLoc(
1053*0fca6ea1SDimitry Andric     SourceLocation Loc) {
1054*0fca6ea1SDimitry Andric   auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1055*0fca6ea1SDimitry Andric   if (!Info) {
1056*0fca6ea1SDimitry Andric     // Don't allocate if the location is invalid.
1057*0fca6ea1SDimitry Andric     if (Loc.isInvalid())
1058*0fca6ea1SDimitry Andric       return;
1059*0fca6ea1SDimitry Andric     Info = new (getASTContext()) ExplicitInstantiationInfo;
1060*0fca6ea1SDimitry Andric     Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1061*0fca6ea1SDimitry Andric     ExplicitInfo = Info;
1062*0fca6ea1SDimitry Andric   }
1063*0fca6ea1SDimitry Andric   Info->TemplateKeywordLoc = Loc;
10640b57cec5SDimitry Andric }
10650b57cec5SDimitry Andric 
10660b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10670b57cec5SDimitry Andric // ConceptDecl Implementation
10680b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10690b57cec5SDimitry Andric ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
10700b57cec5SDimitry Andric                                  SourceLocation L, DeclarationName Name,
10710b57cec5SDimitry Andric                                  TemplateParameterList *Params,
10720b57cec5SDimitry Andric                                  Expr *ConstraintExpr) {
1073349cc55cSDimitry Andric   bool Invalid = AdoptTemplateParameterList(Params, DC);
1074349cc55cSDimitry Andric   auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1075349cc55cSDimitry Andric   if (Invalid)
1076349cc55cSDimitry Andric     TD->setInvalidDecl();
1077349cc55cSDimitry Andric   return TD;
10780b57cec5SDimitry Andric }
10790b57cec5SDimitry Andric 
1080*0fca6ea1SDimitry Andric ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
10810b57cec5SDimitry Andric   ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
10820b57cec5SDimitry Andric                                                 DeclarationName(),
10830b57cec5SDimitry Andric                                                 nullptr, nullptr);
10840b57cec5SDimitry Andric 
10850b57cec5SDimitry Andric   return Result;
10860b57cec5SDimitry Andric }
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1089bdd1243dSDimitry Andric // ImplicitConceptSpecializationDecl Implementation
1090bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
1091bdd1243dSDimitry Andric ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1092bdd1243dSDimitry Andric     DeclContext *DC, SourceLocation SL,
1093bdd1243dSDimitry Andric     ArrayRef<TemplateArgument> ConvertedArgs)
1094bdd1243dSDimitry Andric     : Decl(ImplicitConceptSpecialization, DC, SL),
1095bdd1243dSDimitry Andric       NumTemplateArgs(ConvertedArgs.size()) {
1096bdd1243dSDimitry Andric   setTemplateArguments(ConvertedArgs);
1097bdd1243dSDimitry Andric }
1098bdd1243dSDimitry Andric 
1099bdd1243dSDimitry Andric ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1100bdd1243dSDimitry Andric     EmptyShell Empty, unsigned NumTemplateArgs)
1101bdd1243dSDimitry Andric     : Decl(ImplicitConceptSpecialization, Empty),
1102bdd1243dSDimitry Andric       NumTemplateArgs(NumTemplateArgs) {}
1103bdd1243dSDimitry Andric 
1104bdd1243dSDimitry Andric ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1105bdd1243dSDimitry Andric     const ASTContext &C, DeclContext *DC, SourceLocation SL,
1106bdd1243dSDimitry Andric     ArrayRef<TemplateArgument> ConvertedArgs) {
1107bdd1243dSDimitry Andric   return new (C, DC,
1108bdd1243dSDimitry Andric               additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1109bdd1243dSDimitry Andric       ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1110bdd1243dSDimitry Andric }
1111bdd1243dSDimitry Andric 
1112bdd1243dSDimitry Andric ImplicitConceptSpecializationDecl *
1113bdd1243dSDimitry Andric ImplicitConceptSpecializationDecl::CreateDeserialized(
1114*0fca6ea1SDimitry Andric     const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1115bdd1243dSDimitry Andric   return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1116bdd1243dSDimitry Andric       ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1117bdd1243dSDimitry Andric }
1118bdd1243dSDimitry Andric 
1119bdd1243dSDimitry Andric void ImplicitConceptSpecializationDecl::setTemplateArguments(
1120bdd1243dSDimitry Andric     ArrayRef<TemplateArgument> Converted) {
1121bdd1243dSDimitry Andric   assert(Converted.size() == NumTemplateArgs);
1122bdd1243dSDimitry Andric   std::uninitialized_copy(Converted.begin(), Converted.end(),
1123bdd1243dSDimitry Andric                           getTrailingObjects<TemplateArgument>());
1124bdd1243dSDimitry Andric }
1125bdd1243dSDimitry Andric 
1126bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
11270b57cec5SDimitry Andric // ClassTemplatePartialSpecializationDecl Implementation
11280b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11290b57cec5SDimitry Andric void ClassTemplatePartialSpecializationDecl::anchor() {}
11300b57cec5SDimitry Andric 
1131*0fca6ea1SDimitry Andric ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1132*0fca6ea1SDimitry Andric     ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1133*0fca6ea1SDimitry Andric     SourceLocation IdLoc, TemplateParameterList *Params,
1134*0fca6ea1SDimitry Andric     ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
11350b57cec5SDimitry Andric     ClassTemplatePartialSpecializationDecl *PrevDecl)
1136*0fca6ea1SDimitry Andric     : ClassTemplateSpecializationDecl(
1137*0fca6ea1SDimitry Andric           Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
11380b57cec5SDimitry Andric           SpecializedTemplate, Args, PrevDecl),
1139*0fca6ea1SDimitry Andric       TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1140349cc55cSDimitry Andric   if (AdoptTemplateParameterList(Params, this))
1141349cc55cSDimitry Andric     setInvalidDecl();
11420b57cec5SDimitry Andric }
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *
1145*0fca6ea1SDimitry Andric ClassTemplatePartialSpecializationDecl::Create(
1146*0fca6ea1SDimitry Andric     ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1147*0fca6ea1SDimitry Andric     SourceLocation IdLoc, TemplateParameterList *Params,
1148*0fca6ea1SDimitry Andric     ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
11490b57cec5SDimitry Andric     QualType CanonInjectedType,
11500b57cec5SDimitry Andric     ClassTemplatePartialSpecializationDecl *PrevDecl) {
1151*0fca6ea1SDimitry Andric   auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1152*0fca6ea1SDimitry Andric       Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1153*0fca6ea1SDimitry Andric       PrevDecl);
11540b57cec5SDimitry Andric   Result->setSpecializationKind(TSK_ExplicitSpecialization);
11550b57cec5SDimitry Andric   Result->setMayHaveOutOfDateDef(false);
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric   Context.getInjectedClassNameType(Result, CanonInjectedType);
11580b57cec5SDimitry Andric   return Result;
11590b57cec5SDimitry Andric }
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *
11620b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1163*0fca6ea1SDimitry Andric                                                            GlobalDeclID ID) {
11640b57cec5SDimitry Andric   auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
11650b57cec5SDimitry Andric   Result->setMayHaveOutOfDateDef(false);
11660b57cec5SDimitry Andric   return Result;
11670b57cec5SDimitry Andric }
11680b57cec5SDimitry Andric 
1169*0fca6ea1SDimitry Andric SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
1170*0fca6ea1SDimitry Andric   if (const ClassTemplatePartialSpecializationDecl *MT =
1171*0fca6ea1SDimitry Andric           getInstantiatedFromMember();
1172*0fca6ea1SDimitry Andric       MT && !isMemberSpecialization())
1173*0fca6ea1SDimitry Andric     return MT->getSourceRange();
1174*0fca6ea1SDimitry Andric   SourceRange Range = ClassTemplateSpecializationDecl::getSourceRange();
1175*0fca6ea1SDimitry Andric   if (const TemplateParameterList *TPL = getTemplateParameters();
1176*0fca6ea1SDimitry Andric       TPL && !getNumTemplateParameterLists())
1177*0fca6ea1SDimitry Andric     Range.setBegin(TPL->getTemplateLoc());
1178*0fca6ea1SDimitry Andric   return Range;
1179*0fca6ea1SDimitry Andric }
1180*0fca6ea1SDimitry Andric 
11810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11820b57cec5SDimitry Andric // FriendTemplateDecl Implementation
11830b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11840b57cec5SDimitry Andric 
11850b57cec5SDimitry Andric void FriendTemplateDecl::anchor() {}
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric FriendTemplateDecl *
11880b57cec5SDimitry Andric FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
11890b57cec5SDimitry Andric                            SourceLocation L,
11900b57cec5SDimitry Andric                            MutableArrayRef<TemplateParameterList *> Params,
11910b57cec5SDimitry Andric                            FriendUnion Friend, SourceLocation FLoc) {
1192d781ede6SDimitry Andric   TemplateParameterList **TPL = nullptr;
1193d781ede6SDimitry Andric   if (!Params.empty()) {
1194d781ede6SDimitry Andric     TPL = new (Context) TemplateParameterList *[Params.size()];
1195d781ede6SDimitry Andric     llvm::copy(Params, TPL);
1196d781ede6SDimitry Andric   }
1197d781ede6SDimitry Andric   return new (Context, DC)
1198d781ede6SDimitry Andric       FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
11990b57cec5SDimitry Andric }
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1202*0fca6ea1SDimitry Andric                                                            GlobalDeclID ID) {
12030b57cec5SDimitry Andric   return new (C, ID) FriendTemplateDecl(EmptyShell());
12040b57cec5SDimitry Andric }
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12070b57cec5SDimitry Andric // TypeAliasTemplateDecl Implementation
12080b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12090b57cec5SDimitry Andric 
1210349cc55cSDimitry Andric TypeAliasTemplateDecl *
1211349cc55cSDimitry Andric TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
12120b57cec5SDimitry Andric                               DeclarationName Name,
1213349cc55cSDimitry Andric                               TemplateParameterList *Params, NamedDecl *Decl) {
1214349cc55cSDimitry Andric   bool Invalid = AdoptTemplateParameterList(Params, DC);
1215349cc55cSDimitry Andric   auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1216349cc55cSDimitry Andric   if (Invalid)
1217349cc55cSDimitry Andric     TD->setInvalidDecl();
1218349cc55cSDimitry Andric   return TD;
12190b57cec5SDimitry Andric }
12200b57cec5SDimitry Andric 
1221*0fca6ea1SDimitry Andric TypeAliasTemplateDecl *
1222*0fca6ea1SDimitry Andric TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
12230b57cec5SDimitry Andric   return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
12240b57cec5SDimitry Andric                                            DeclarationName(), nullptr, nullptr);
12250b57cec5SDimitry Andric }
12260b57cec5SDimitry Andric 
12270b57cec5SDimitry Andric RedeclarableTemplateDecl::CommonBase *
12280b57cec5SDimitry Andric TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
12290b57cec5SDimitry Andric   auto *CommonPtr = new (C) Common;
12300b57cec5SDimitry Andric   C.addDestruction(CommonPtr);
12310b57cec5SDimitry Andric   return CommonPtr;
12320b57cec5SDimitry Andric }
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12350b57cec5SDimitry Andric // VarTemplateDecl Implementation
12360b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric VarTemplateDecl *VarTemplateDecl::getDefinition() {
12390b57cec5SDimitry Andric   VarTemplateDecl *CurD = this;
12400b57cec5SDimitry Andric   while (CurD) {
12410b57cec5SDimitry Andric     if (CurD->isThisDeclarationADefinition())
12420b57cec5SDimitry Andric       return CurD;
12430b57cec5SDimitry Andric     CurD = CurD->getPreviousDecl();
12440b57cec5SDimitry Andric   }
12450b57cec5SDimitry Andric   return nullptr;
12460b57cec5SDimitry Andric }
12470b57cec5SDimitry Andric 
12480b57cec5SDimitry Andric VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
12490b57cec5SDimitry Andric                                          SourceLocation L, DeclarationName Name,
12500b57cec5SDimitry Andric                                          TemplateParameterList *Params,
12510b57cec5SDimitry Andric                                          VarDecl *Decl) {
1252349cc55cSDimitry Andric   bool Invalid = AdoptTemplateParameterList(Params, DC);
1253349cc55cSDimitry Andric   auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1254349cc55cSDimitry Andric   if (Invalid)
1255349cc55cSDimitry Andric     TD->setInvalidDecl();
1256349cc55cSDimitry Andric   return TD;
12570b57cec5SDimitry Andric }
12580b57cec5SDimitry Andric 
12590b57cec5SDimitry Andric VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1260*0fca6ea1SDimitry Andric                                                      GlobalDeclID ID) {
12610b57cec5SDimitry Andric   return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
12620b57cec5SDimitry Andric                                      DeclarationName(), nullptr, nullptr);
12630b57cec5SDimitry Andric }
12640b57cec5SDimitry Andric 
12650b57cec5SDimitry Andric void VarTemplateDecl::LoadLazySpecializations() const {
12660b57cec5SDimitry Andric   loadLazySpecializationsImpl();
12670b57cec5SDimitry Andric }
12680b57cec5SDimitry Andric 
12690b57cec5SDimitry Andric llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
12700b57cec5SDimitry Andric VarTemplateDecl::getSpecializations() const {
12710b57cec5SDimitry Andric   LoadLazySpecializations();
12720b57cec5SDimitry Andric   return getCommonPtr()->Specializations;
12730b57cec5SDimitry Andric }
12740b57cec5SDimitry Andric 
12750b57cec5SDimitry Andric llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1276e8d8bef9SDimitry Andric VarTemplateDecl::getPartialSpecializations() const {
12770b57cec5SDimitry Andric   LoadLazySpecializations();
12780b57cec5SDimitry Andric   return getCommonPtr()->PartialSpecializations;
12790b57cec5SDimitry Andric }
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric RedeclarableTemplateDecl::CommonBase *
12820b57cec5SDimitry Andric VarTemplateDecl::newCommon(ASTContext &C) const {
12830b57cec5SDimitry Andric   auto *CommonPtr = new (C) Common;
12840b57cec5SDimitry Andric   C.addDestruction(CommonPtr);
12850b57cec5SDimitry Andric   return CommonPtr;
12860b57cec5SDimitry Andric }
12870b57cec5SDimitry Andric 
12880b57cec5SDimitry Andric VarTemplateSpecializationDecl *
12890b57cec5SDimitry Andric VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
12900b57cec5SDimitry Andric                                     void *&InsertPos) {
1291480093f4SDimitry Andric   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
12920b57cec5SDimitry Andric }
12930b57cec5SDimitry Andric 
12940b57cec5SDimitry Andric void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
12950b57cec5SDimitry Andric                                         void *InsertPos) {
12960b57cec5SDimitry Andric   addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
12970b57cec5SDimitry Andric }
12980b57cec5SDimitry Andric 
12990b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl *
13000b57cec5SDimitry Andric VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1301480093f4SDimitry Andric      TemplateParameterList *TPL, void *&InsertPos) {
1302480093f4SDimitry Andric   return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1303480093f4SDimitry Andric                                 TPL);
1304480093f4SDimitry Andric }
1305480093f4SDimitry Andric 
130606c3fb27SDimitry Andric void VarTemplatePartialSpecializationDecl::Profile(
130706c3fb27SDimitry Andric     llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
130806c3fb27SDimitry Andric     TemplateParameterList *TPL, const ASTContext &Context) {
1309480093f4SDimitry Andric   ID.AddInteger(TemplateArgs.size());
1310480093f4SDimitry Andric   for (const TemplateArgument &TemplateArg : TemplateArgs)
1311480093f4SDimitry Andric     TemplateArg.Profile(ID, Context);
131206c3fb27SDimitry Andric   TPL->Profile(ID, Context);
13130b57cec5SDimitry Andric }
13140b57cec5SDimitry Andric 
13150b57cec5SDimitry Andric void VarTemplateDecl::AddPartialSpecialization(
13160b57cec5SDimitry Andric     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
13170b57cec5SDimitry Andric   if (InsertPos)
13180b57cec5SDimitry Andric     getPartialSpecializations().InsertNode(D, InsertPos);
13190b57cec5SDimitry Andric   else {
13200b57cec5SDimitry Andric     VarTemplatePartialSpecializationDecl *Existing =
13210b57cec5SDimitry Andric         getPartialSpecializations().GetOrInsertNode(D);
13220b57cec5SDimitry Andric     (void)Existing;
13230b57cec5SDimitry Andric     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
13240b57cec5SDimitry Andric   }
13250b57cec5SDimitry Andric 
13260b57cec5SDimitry Andric   if (ASTMutationListener *L = getASTMutationListener())
13270b57cec5SDimitry Andric     L->AddedCXXTemplateSpecialization(this, D);
13280b57cec5SDimitry Andric }
13290b57cec5SDimitry Andric 
13300b57cec5SDimitry Andric void VarTemplateDecl::getPartialSpecializations(
1331e8d8bef9SDimitry Andric     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
13320b57cec5SDimitry Andric   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
13330b57cec5SDimitry Andric       getPartialSpecializations();
13340b57cec5SDimitry Andric   PS.clear();
13350b57cec5SDimitry Andric   PS.reserve(PartialSpecs.size());
13360b57cec5SDimitry Andric   for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
13370b57cec5SDimitry Andric     PS.push_back(P.getMostRecentDecl());
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl *
13410b57cec5SDimitry Andric VarTemplateDecl::findPartialSpecInstantiatedFromMember(
13420b57cec5SDimitry Andric     VarTemplatePartialSpecializationDecl *D) {
13430b57cec5SDimitry Andric   Decl *DCanon = D->getCanonicalDecl();
13440b57cec5SDimitry Andric   for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
13450b57cec5SDimitry Andric     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
13460b57cec5SDimitry Andric       return P.getMostRecentDecl();
13470b57cec5SDimitry Andric   }
13480b57cec5SDimitry Andric 
13490b57cec5SDimitry Andric   return nullptr;
13500b57cec5SDimitry Andric }
13510b57cec5SDimitry Andric 
13520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13530b57cec5SDimitry Andric // VarTemplateSpecializationDecl Implementation
13540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13550b57cec5SDimitry Andric 
13560b57cec5SDimitry Andric VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
13570b57cec5SDimitry Andric     Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
13580b57cec5SDimitry Andric     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
13590b57cec5SDimitry Andric     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
13600b57cec5SDimitry Andric     : VarDecl(DK, Context, DC, StartLoc, IdLoc,
13610b57cec5SDimitry Andric               SpecializedTemplate->getIdentifier(), T, TInfo, S),
13620b57cec5SDimitry Andric       SpecializedTemplate(SpecializedTemplate),
13630b57cec5SDimitry Andric       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
13640b57cec5SDimitry Andric       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
13650b57cec5SDimitry Andric 
13660b57cec5SDimitry Andric VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
13670b57cec5SDimitry Andric                                                              ASTContext &C)
13680b57cec5SDimitry Andric     : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
13690b57cec5SDimitry Andric               QualType(), nullptr, SC_None),
13700b57cec5SDimitry Andric       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
13710b57cec5SDimitry Andric 
13720b57cec5SDimitry Andric VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
13730b57cec5SDimitry Andric     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
13740b57cec5SDimitry Andric     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
13750b57cec5SDimitry Andric     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
13760b57cec5SDimitry Andric   return new (Context, DC) VarTemplateSpecializationDecl(
13770b57cec5SDimitry Andric       VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
13780b57cec5SDimitry Andric       SpecializedTemplate, T, TInfo, S, Args);
13790b57cec5SDimitry Andric }
13800b57cec5SDimitry Andric 
13810b57cec5SDimitry Andric VarTemplateSpecializationDecl *
1382*0fca6ea1SDimitry Andric VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
1383*0fca6ea1SDimitry Andric                                                   GlobalDeclID ID) {
13840b57cec5SDimitry Andric   return new (C, ID)
13850b57cec5SDimitry Andric       VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
13860b57cec5SDimitry Andric }
13870b57cec5SDimitry Andric 
13880b57cec5SDimitry Andric void VarTemplateSpecializationDecl::getNameForDiagnostic(
13890b57cec5SDimitry Andric     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
13900b57cec5SDimitry Andric   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
13910b57cec5SDimitry Andric 
13920b57cec5SDimitry Andric   const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
13930b57cec5SDimitry Andric   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
13940b57cec5SDimitry Andric           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1395e8d8bef9SDimitry Andric     printTemplateArgumentList(
1396e8d8bef9SDimitry Andric         OS, ArgsAsWritten->arguments(), Policy,
1397e8d8bef9SDimitry Andric         getSpecializedTemplate()->getTemplateParameters());
13980b57cec5SDimitry Andric   } else {
13990b57cec5SDimitry Andric     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1400e8d8bef9SDimitry Andric     printTemplateArgumentList(
1401e8d8bef9SDimitry Andric         OS, TemplateArgs.asArray(), Policy,
1402e8d8bef9SDimitry Andric         getSpecializedTemplate()->getTemplateParameters());
14030b57cec5SDimitry Andric   }
14040b57cec5SDimitry Andric }
14050b57cec5SDimitry Andric 
14060b57cec5SDimitry Andric VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
14070b57cec5SDimitry Andric   if (const auto *PartialSpec =
14080b57cec5SDimitry Andric           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
14090b57cec5SDimitry Andric     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
14100b57cec5SDimitry Andric   return SpecializedTemplate.get<VarTemplateDecl *>();
14110b57cec5SDimitry Andric }
14120b57cec5SDimitry Andric 
141306c3fb27SDimitry Andric SourceRange VarTemplateSpecializationDecl::getSourceRange() const {
1414*0fca6ea1SDimitry Andric   switch (getSpecializationKind()) {
1415*0fca6ea1SDimitry Andric   case TSK_Undeclared:
1416*0fca6ea1SDimitry Andric   case TSK_ImplicitInstantiation: {
1417*0fca6ea1SDimitry Andric     llvm::PointerUnion<VarTemplateDecl *,
1418*0fca6ea1SDimitry Andric                        VarTemplatePartialSpecializationDecl *>
1419*0fca6ea1SDimitry Andric         Pattern = getSpecializedTemplateOrPartial();
1420*0fca6ea1SDimitry Andric     assert(!Pattern.isNull() &&
1421*0fca6ea1SDimitry Andric            "Variable template specialization without pattern?");
1422*0fca6ea1SDimitry Andric     if (const auto *VTPSD =
1423*0fca6ea1SDimitry Andric             Pattern.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1424*0fca6ea1SDimitry Andric       return VTPSD->getSourceRange();
1425*0fca6ea1SDimitry Andric     VarTemplateDecl *VTD = Pattern.get<VarTemplateDecl *>();
1426*0fca6ea1SDimitry Andric     if (hasInit()) {
1427*0fca6ea1SDimitry Andric       if (VarTemplateDecl *Definition = VTD->getDefinition())
1428*0fca6ea1SDimitry Andric         return Definition->getSourceRange();
142906c3fb27SDimitry Andric     }
1430*0fca6ea1SDimitry Andric     return VTD->getCanonicalDecl()->getSourceRange();
1431*0fca6ea1SDimitry Andric   }
1432*0fca6ea1SDimitry Andric   case TSK_ExplicitSpecialization: {
1433*0fca6ea1SDimitry Andric     SourceRange Range = VarDecl::getSourceRange();
1434*0fca6ea1SDimitry Andric     if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
1435*0fca6ea1SDimitry Andric         !hasInit() && Args)
1436*0fca6ea1SDimitry Andric       Range.setEnd(Args->getRAngleLoc());
1437*0fca6ea1SDimitry Andric     return Range;
1438*0fca6ea1SDimitry Andric   }
1439*0fca6ea1SDimitry Andric   case TSK_ExplicitInstantiationDeclaration:
1440*0fca6ea1SDimitry Andric   case TSK_ExplicitInstantiationDefinition: {
1441*0fca6ea1SDimitry Andric     SourceRange Range = VarDecl::getSourceRange();
1442*0fca6ea1SDimitry Andric     if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1443*0fca6ea1SDimitry Andric       Range.setBegin(ExternKW);
1444*0fca6ea1SDimitry Andric     else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1445*0fca6ea1SDimitry Andric              TemplateKW.isValid())
1446*0fca6ea1SDimitry Andric       Range.setBegin(TemplateKW);
1447*0fca6ea1SDimitry Andric     if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
1448*0fca6ea1SDimitry Andric       Range.setEnd(Args->getRAngleLoc());
1449*0fca6ea1SDimitry Andric     return Range;
1450*0fca6ea1SDimitry Andric   }
1451*0fca6ea1SDimitry Andric   }
1452*0fca6ea1SDimitry Andric   llvm_unreachable("unhandled template specialization kind");
145306c3fb27SDimitry Andric }
145406c3fb27SDimitry Andric 
1455*0fca6ea1SDimitry Andric void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
1456*0fca6ea1SDimitry Andric   auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1457*0fca6ea1SDimitry Andric   if (!Info) {
1458*0fca6ea1SDimitry Andric     // Don't allocate if the location is invalid.
1459*0fca6ea1SDimitry Andric     if (Loc.isInvalid())
1460*0fca6ea1SDimitry Andric       return;
1461*0fca6ea1SDimitry Andric     Info = new (getASTContext()) ExplicitInstantiationInfo;
1462*0fca6ea1SDimitry Andric     Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1463*0fca6ea1SDimitry Andric     ExplicitInfo = Info;
1464*0fca6ea1SDimitry Andric   }
1465*0fca6ea1SDimitry Andric   Info->ExternKeywordLoc = Loc;
1466*0fca6ea1SDimitry Andric }
1467*0fca6ea1SDimitry Andric 
1468*0fca6ea1SDimitry Andric void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) {
1469*0fca6ea1SDimitry Andric   auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1470*0fca6ea1SDimitry Andric   if (!Info) {
1471*0fca6ea1SDimitry Andric     // Don't allocate if the location is invalid.
1472*0fca6ea1SDimitry Andric     if (Loc.isInvalid())
1473*0fca6ea1SDimitry Andric       return;
1474*0fca6ea1SDimitry Andric     Info = new (getASTContext()) ExplicitInstantiationInfo;
1475*0fca6ea1SDimitry Andric     Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1476*0fca6ea1SDimitry Andric     ExplicitInfo = Info;
1477*0fca6ea1SDimitry Andric   }
1478*0fca6ea1SDimitry Andric   Info->TemplateKeywordLoc = Loc;
1479*0fca6ea1SDimitry Andric }
148006c3fb27SDimitry Andric 
14810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14820b57cec5SDimitry Andric // VarTemplatePartialSpecializationDecl Implementation
14830b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric void VarTemplatePartialSpecializationDecl::anchor() {}
14860b57cec5SDimitry Andric 
14870b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
14880b57cec5SDimitry Andric     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
14890b57cec5SDimitry Andric     SourceLocation IdLoc, TemplateParameterList *Params,
14900b57cec5SDimitry Andric     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1491*0fca6ea1SDimitry Andric     StorageClass S, ArrayRef<TemplateArgument> Args)
14920b57cec5SDimitry Andric     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
14930b57cec5SDimitry Andric                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
14940b57cec5SDimitry Andric                                     TInfo, S, Args),
1495*0fca6ea1SDimitry Andric       TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1496349cc55cSDimitry Andric   if (AdoptTemplateParameterList(Params, DC))
1497349cc55cSDimitry Andric     setInvalidDecl();
14980b57cec5SDimitry Andric }
14990b57cec5SDimitry Andric 
15000b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl *
15010b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl::Create(
15020b57cec5SDimitry Andric     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
15030b57cec5SDimitry Andric     SourceLocation IdLoc, TemplateParameterList *Params,
15040b57cec5SDimitry Andric     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1505*0fca6ea1SDimitry Andric     StorageClass S, ArrayRef<TemplateArgument> Args) {
1506*0fca6ea1SDimitry Andric   auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1507*0fca6ea1SDimitry Andric       Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1508*0fca6ea1SDimitry Andric       Args);
15090b57cec5SDimitry Andric   Result->setSpecializationKind(TSK_ExplicitSpecialization);
15100b57cec5SDimitry Andric   return Result;
15110b57cec5SDimitry Andric }
15120b57cec5SDimitry Andric 
15130b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl *
15140b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1515*0fca6ea1SDimitry Andric                                                          GlobalDeclID ID) {
15160b57cec5SDimitry Andric   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
15170b57cec5SDimitry Andric }
15180b57cec5SDimitry Andric 
151906c3fb27SDimitry Andric SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
1520*0fca6ea1SDimitry Andric   if (const VarTemplatePartialSpecializationDecl *MT =
1521*0fca6ea1SDimitry Andric           getInstantiatedFromMember();
1522*0fca6ea1SDimitry Andric       MT && !isMemberSpecialization())
1523*0fca6ea1SDimitry Andric     return MT->getSourceRange();
1524*0fca6ea1SDimitry Andric   SourceRange Range = VarTemplateSpecializationDecl::getSourceRange();
1525*0fca6ea1SDimitry Andric   if (const TemplateParameterList *TPL = getTemplateParameters();
1526*0fca6ea1SDimitry Andric       TPL && !getNumTemplateParameterLists())
1527*0fca6ea1SDimitry Andric     Range.setBegin(TPL->getTemplateLoc());
1528*0fca6ea1SDimitry Andric   return Range;
152906c3fb27SDimitry Andric }
153006c3fb27SDimitry Andric 
15310b57cec5SDimitry Andric static TemplateParameterList *
15320b57cec5SDimitry Andric createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
15330b57cec5SDimitry Andric   // typename T
15340b57cec5SDimitry Andric   auto *T = TemplateTypeParmDecl::Create(
15350b57cec5SDimitry Andric       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1536480093f4SDimitry Andric       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1537480093f4SDimitry Andric       /*HasTypeConstraint=*/false);
15380b57cec5SDimitry Andric   T->setImplicit(true);
15390b57cec5SDimitry Andric 
15400b57cec5SDimitry Andric   // T ...Ints
15410b57cec5SDimitry Andric   TypeSourceInfo *TI =
15420b57cec5SDimitry Andric       C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
15430b57cec5SDimitry Andric   auto *N = NonTypeTemplateParmDecl::Create(
15440b57cec5SDimitry Andric       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
15450b57cec5SDimitry Andric       /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
15460b57cec5SDimitry Andric   N->setImplicit(true);
15470b57cec5SDimitry Andric 
15480b57cec5SDimitry Andric   // <typename T, T ...Ints>
15490b57cec5SDimitry Andric   NamedDecl *P[2] = {T, N};
15500b57cec5SDimitry Andric   auto *TPL = TemplateParameterList::Create(
15510b57cec5SDimitry Andric       C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric   // template <typename T, ...Ints> class IntSeq
15540b57cec5SDimitry Andric   auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
15550b57cec5SDimitry Andric       C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1556*0fca6ea1SDimitry Andric       /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL);
15570b57cec5SDimitry Andric   TemplateTemplateParm->setImplicit(true);
15580b57cec5SDimitry Andric 
15590b57cec5SDimitry Andric   // typename T
15600b57cec5SDimitry Andric   auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
15610b57cec5SDimitry Andric       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1562480093f4SDimitry Andric       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1563480093f4SDimitry Andric       /*HasTypeConstraint=*/false);
15640b57cec5SDimitry Andric   TemplateTypeParm->setImplicit(true);
15650b57cec5SDimitry Andric 
15660b57cec5SDimitry Andric   // T N
15670b57cec5SDimitry Andric   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
15680b57cec5SDimitry Andric       QualType(TemplateTypeParm->getTypeForDecl(), 0));
15690b57cec5SDimitry Andric   auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
15700b57cec5SDimitry Andric       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
15710b57cec5SDimitry Andric       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
15720b57cec5SDimitry Andric   NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
15730b57cec5SDimitry Andric                          NonTypeTemplateParm};
15740b57cec5SDimitry Andric 
15750b57cec5SDimitry Andric   // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
15760b57cec5SDimitry Andric   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
15770b57cec5SDimitry Andric                                        Params, SourceLocation(), nullptr);
15780b57cec5SDimitry Andric }
15790b57cec5SDimitry Andric 
15800b57cec5SDimitry Andric static TemplateParameterList *
15810b57cec5SDimitry Andric createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
15820b57cec5SDimitry Andric   // std::size_t Index
15830b57cec5SDimitry Andric   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
15840b57cec5SDimitry Andric   auto *Index = NonTypeTemplateParmDecl::Create(
15850b57cec5SDimitry Andric       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
15860b57cec5SDimitry Andric       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
15870b57cec5SDimitry Andric 
15880b57cec5SDimitry Andric   // typename ...T
15890b57cec5SDimitry Andric   auto *Ts = TemplateTypeParmDecl::Create(
15900b57cec5SDimitry Andric       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1591480093f4SDimitry Andric       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1592480093f4SDimitry Andric       /*HasTypeConstraint=*/false);
15930b57cec5SDimitry Andric   Ts->setImplicit(true);
15940b57cec5SDimitry Andric 
15950b57cec5SDimitry Andric   // template <std::size_t Index, typename ...T>
15960b57cec5SDimitry Andric   NamedDecl *Params[] = {Index, Ts};
15970b57cec5SDimitry Andric   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1598bdd1243dSDimitry Andric                                        llvm::ArrayRef(Params), SourceLocation(),
1599bdd1243dSDimitry Andric                                        nullptr);
16000b57cec5SDimitry Andric }
16010b57cec5SDimitry Andric 
16020b57cec5SDimitry Andric static TemplateParameterList *createBuiltinTemplateParameterList(
16030b57cec5SDimitry Andric     const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
16040b57cec5SDimitry Andric   switch (BTK) {
16050b57cec5SDimitry Andric   case BTK__make_integer_seq:
16060b57cec5SDimitry Andric     return createMakeIntegerSeqParameterList(C, DC);
16070b57cec5SDimitry Andric   case BTK__type_pack_element:
16080b57cec5SDimitry Andric     return createTypePackElementParameterList(C, DC);
16090b57cec5SDimitry Andric   }
16100b57cec5SDimitry Andric 
16110b57cec5SDimitry Andric   llvm_unreachable("unhandled BuiltinTemplateKind!");
16120b57cec5SDimitry Andric }
16130b57cec5SDimitry Andric 
16140b57cec5SDimitry Andric void BuiltinTemplateDecl::anchor() {}
16150b57cec5SDimitry Andric 
16160b57cec5SDimitry Andric BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
16170b57cec5SDimitry Andric                                          DeclarationName Name,
16180b57cec5SDimitry Andric                                          BuiltinTemplateKind BTK)
16190b57cec5SDimitry Andric     : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
16200b57cec5SDimitry Andric                    createBuiltinTemplateParameterList(C, DC, BTK)),
16210b57cec5SDimitry Andric       BTK(BTK) {}
1622480093f4SDimitry Andric 
1623e8d8bef9SDimitry Andric TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1624e8d8bef9SDimitry Andric                                                          QualType T,
1625e8d8bef9SDimitry Andric                                                          const APValue &V) {
1626e8d8bef9SDimitry Andric   DeclContext *DC = C.getTranslationUnitDecl();
1627e8d8bef9SDimitry Andric   auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1628e8d8bef9SDimitry Andric   C.addDestruction(&TPOD->Value);
1629e8d8bef9SDimitry Andric   return TPOD;
1630e8d8bef9SDimitry Andric }
1631e8d8bef9SDimitry Andric 
1632e8d8bef9SDimitry Andric TemplateParamObjectDecl *
1633*0fca6ea1SDimitry Andric TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1634e8d8bef9SDimitry Andric   auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1635e8d8bef9SDimitry Andric   C.addDestruction(&TPOD->Value);
1636e8d8bef9SDimitry Andric   return TPOD;
1637e8d8bef9SDimitry Andric }
1638e8d8bef9SDimitry Andric 
1639bdd1243dSDimitry Andric void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1640bdd1243dSDimitry Andric                                         const PrintingPolicy &Policy) const {
1641e8d8bef9SDimitry Andric   OS << "<template param ";
1642bdd1243dSDimitry Andric   printAsExpr(OS, Policy);
1643e8d8bef9SDimitry Andric   OS << ">";
1644e8d8bef9SDimitry Andric }
1645e8d8bef9SDimitry Andric 
1646e8d8bef9SDimitry Andric void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
164781ad6265SDimitry Andric   printAsExpr(OS, getASTContext().getPrintingPolicy());
164881ad6265SDimitry Andric }
164981ad6265SDimitry Andric 
165081ad6265SDimitry Andric void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
165181ad6265SDimitry Andric                                           const PrintingPolicy &Policy) const {
165281ad6265SDimitry Andric   getType().getUnqualifiedType().print(OS, Policy);
165381ad6265SDimitry Andric   printAsInit(OS, Policy);
1654e8d8bef9SDimitry Andric }
1655e8d8bef9SDimitry Andric 
1656e8d8bef9SDimitry Andric void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
165781ad6265SDimitry Andric   printAsInit(OS, getASTContext().getPrintingPolicy());
165881ad6265SDimitry Andric }
165981ad6265SDimitry Andric 
166081ad6265SDimitry Andric void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
166181ad6265SDimitry Andric                                           const PrintingPolicy &Policy) const {
166281ad6265SDimitry Andric   getValue().printPretty(OS, Policy, getType(), &getASTContext());
1663e8d8bef9SDimitry Andric }
1664bdd1243dSDimitry Andric 
1665bdd1243dSDimitry Andric TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
1666bdd1243dSDimitry Andric   switch (D->getKind()) {
1667*0fca6ea1SDimitry Andric   case Decl::Kind::CXXRecord:
1668*0fca6ea1SDimitry Andric     return cast<CXXRecordDecl>(D)
1669*0fca6ea1SDimitry Andric         ->getDescribedTemplate()
1670*0fca6ea1SDimitry Andric         ->getTemplateParameters();
1671bdd1243dSDimitry Andric   case Decl::Kind::ClassTemplate:
1672bdd1243dSDimitry Andric     return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1673bdd1243dSDimitry Andric   case Decl::Kind::ClassTemplateSpecialization: {
1674bdd1243dSDimitry Andric     const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1675bdd1243dSDimitry Andric     auto P = CTSD->getSpecializedTemplateOrPartial();
1676bdd1243dSDimitry Andric     if (const auto *CTPSD =
1677bdd1243dSDimitry Andric             P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1678bdd1243dSDimitry Andric       return CTPSD->getTemplateParameters();
1679bdd1243dSDimitry Andric     return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1680bdd1243dSDimitry Andric   }
1681bdd1243dSDimitry Andric   case Decl::Kind::ClassTemplatePartialSpecialization:
1682bdd1243dSDimitry Andric     return cast<ClassTemplatePartialSpecializationDecl>(D)
1683bdd1243dSDimitry Andric         ->getTemplateParameters();
1684bdd1243dSDimitry Andric   case Decl::Kind::TypeAliasTemplate:
1685bdd1243dSDimitry Andric     return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1686bdd1243dSDimitry Andric   case Decl::Kind::BuiltinTemplate:
1687bdd1243dSDimitry Andric     return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1688bdd1243dSDimitry Andric   case Decl::Kind::CXXDeductionGuide:
1689bdd1243dSDimitry Andric   case Decl::Kind::CXXConversion:
1690bdd1243dSDimitry Andric   case Decl::Kind::CXXConstructor:
1691bdd1243dSDimitry Andric   case Decl::Kind::CXXDestructor:
1692bdd1243dSDimitry Andric   case Decl::Kind::CXXMethod:
1693bdd1243dSDimitry Andric   case Decl::Kind::Function:
1694bdd1243dSDimitry Andric     return cast<FunctionDecl>(D)
1695bdd1243dSDimitry Andric         ->getTemplateSpecializationInfo()
1696bdd1243dSDimitry Andric         ->getTemplate()
1697bdd1243dSDimitry Andric         ->getTemplateParameters();
1698bdd1243dSDimitry Andric   case Decl::Kind::FunctionTemplate:
1699bdd1243dSDimitry Andric     return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1700bdd1243dSDimitry Andric   case Decl::Kind::VarTemplate:
1701bdd1243dSDimitry Andric     return cast<VarTemplateDecl>(D)->getTemplateParameters();
1702bdd1243dSDimitry Andric   case Decl::Kind::VarTemplateSpecialization: {
1703bdd1243dSDimitry Andric     const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1704bdd1243dSDimitry Andric     auto P = VTSD->getSpecializedTemplateOrPartial();
1705bdd1243dSDimitry Andric     if (const auto *VTPSD =
1706bdd1243dSDimitry Andric             P.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1707bdd1243dSDimitry Andric       return VTPSD->getTemplateParameters();
1708bdd1243dSDimitry Andric     return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1709bdd1243dSDimitry Andric   }
1710bdd1243dSDimitry Andric   case Decl::Kind::VarTemplatePartialSpecialization:
1711bdd1243dSDimitry Andric     return cast<VarTemplatePartialSpecializationDecl>(D)
1712bdd1243dSDimitry Andric         ->getTemplateParameters();
1713bdd1243dSDimitry Andric   case Decl::Kind::TemplateTemplateParm:
1714bdd1243dSDimitry Andric     return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1715bdd1243dSDimitry Andric   case Decl::Kind::Concept:
1716bdd1243dSDimitry Andric     return cast<ConceptDecl>(D)->getTemplateParameters();
1717bdd1243dSDimitry Andric   default:
1718bdd1243dSDimitry Andric     llvm_unreachable("Unhandled templated declaration kind");
1719bdd1243dSDimitry Andric   }
1720bdd1243dSDimitry Andric }
1721