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