Bug Summary

File:build/source/clang/lib/AST/DeclTemplate.cpp
Warning:line 87, column 9
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

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