Bug Summary

File:src/gnu/usr.bin/clang/libclangAST/../../../llvm/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 amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DeclTemplate.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/libclangAST/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/libclangAST/obj/../include/clang/AST -I /usr/src/gnu/usr.bin/clang/libclangAST/../../../llvm/clang/include -I /usr/src/gnu/usr.bin/clang/libclangAST/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/libclangAST/../include -I /usr/src/gnu/usr.bin/clang/libclangAST/obj -I /usr/src/gnu/usr.bin/clang/libclangAST/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/libclangAST/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/libclangAST/../../../llvm/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/None.h"
30#include "llvm/ADT/PointerUnion.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
16
Assuming 'Idx' is >= field 'NumParams'
17
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 'NonTypeTemplateParmDecl'
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 'TemplateTemplateParmDecl'
14
Taking true branch
68 if (!IsPack &&
15
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("unexpcted template parameter type")__builtin_unreachable();
81 }
82 // FIXME: If a default argument contains an unexpanded parameter pack, the
83 // template parameter list does too.
84 }
85
86 if (HasRequiresClause) {
18
Assuming field 'HasRequiresClause' is not equal to 0
19
Taking true branch
87 if (RequiresClause->containsUnexpandedParameterPack())
20
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 void AdoptTemplateParameterList(TemplateParameterList *Params,
169 DeclContext *Owner) {
170 for (NamedDecl *P : *Params) {
171 P->setDeclContext(Owner);
172
173 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
174 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
175 }
176}
177
178void TemplateParameterList::
179getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
180 if (HasConstrainedParameters)
181 for (const NamedDecl *Param : *this) {
182 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
183 if (const auto *TC = TTP->getTypeConstraint())
184 AC.push_back(TC->getImmediatelyDeclaredConstraint());
185 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
186 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
187 AC.push_back(E);
188 }
189 }
190 if (HasRequiresClause)
191 AC.push_back(getRequiresClause());
192}
193
194bool TemplateParameterList::hasAssociatedConstraints() const {
195 return HasRequiresClause || HasConstrainedParameters;
196}
197
198bool TemplateParameterList::shouldIncludeTypeForArgument(
199 const TemplateParameterList *TPL, unsigned Idx) {
200 if (!TPL || Idx >= TPL->size())
201 return true;
202 const NamedDecl *TemplParam = TPL->getParam(Idx);
203 if (const auto *ParamValueDecl =
204 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
205 if (ParamValueDecl->getType()->getContainedDeducedType())
206 return true;
207 return false;
208}
209
210namespace clang {
211
212void *allocateDefaultArgStorageChain(const ASTContext &C) {
213 return new (C) char[sizeof(void*) * 2];
214}
215
216} // namespace clang
217
218//===----------------------------------------------------------------------===//
219// TemplateDecl Implementation
220//===----------------------------------------------------------------------===//
221
222TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
223 DeclarationName Name, TemplateParameterList *Params,
224 NamedDecl *Decl)
225 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
226
227void TemplateDecl::anchor() {}
228
229void TemplateDecl::
230getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
231 TemplateParams->getAssociatedConstraints(AC);
232 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
233 if (const Expr *TRC = FD->getTrailingRequiresClause())
234 AC.push_back(TRC);
235}
236
237bool TemplateDecl::hasAssociatedConstraints() const {
238 if (TemplateParams->hasAssociatedConstraints())
239 return true;
240 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
241 return FD->getTrailingRequiresClause();
242 return false;
243}
244
245//===----------------------------------------------------------------------===//
246// RedeclarableTemplateDecl Implementation
247//===----------------------------------------------------------------------===//
248
249void RedeclarableTemplateDecl::anchor() {}
250
251RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
252 if (Common)
253 return Common;
254
255 // Walk the previous-declaration chain until we either find a declaration
256 // with a common pointer or we run out of previous declarations.
257 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
258 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
259 Prev = Prev->getPreviousDecl()) {
260 if (Prev->Common) {
261 Common = Prev->Common;
262 break;
263 }
264
265 PrevDecls.push_back(Prev);
266 }
267
268 // If we never found a common pointer, allocate one now.
269 if (!Common) {
270 // FIXME: If any of the declarations is from an AST file, we probably
271 // need an update record to add the common data.
272
273 Common = newCommon(getASTContext());
274 }
275
276 // Update any previous declarations we saw with the common pointer.
277 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
278 Prev->Common = Common;
279
280 return Common;
281}
282
283void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
284 // Grab the most recent declaration to ensure we've loaded any lazy
285 // redeclarations of this template.
286 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
287 if (CommonBasePtr->LazySpecializations) {
288 ASTContext &Context = getASTContext();
289 uint32_t *Specs = CommonBasePtr->LazySpecializations;
290 CommonBasePtr->LazySpecializations = nullptr;
291 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
292 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
293 }
294}
295
296template<class EntryType, typename... ProfileArguments>
297typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
298RedeclarableTemplateDecl::findSpecializationImpl(
299 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
300 ProfileArguments&&... ProfileArgs) {
301 using SETraits = SpecEntryTraits<EntryType>;
302
303 llvm::FoldingSetNodeID ID;
304 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
305 getASTContext());
306 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
307 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
308}
309
310template<class Derived, class EntryType>
311void RedeclarableTemplateDecl::addSpecializationImpl(
312 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
313 void *InsertPos) {
314 using SETraits = SpecEntryTraits<EntryType>;
315
316 if (InsertPos) {
317#ifndef NDEBUG1
318 void *CorrectInsertPos;
319 assert(!findSpecializationImpl(Specializations,((void)0)
320 CorrectInsertPos,((void)0)
321 SETraits::getTemplateArgs(Entry)) &&((void)0)
322 InsertPos == CorrectInsertPos &&((void)0)
323 "given incorrect InsertPos for specialization")((void)0);
324#endif
325 Specializations.InsertNode(Entry, InsertPos);
326 } else {
327 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
328 (void)Existing;
329 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&((void)0)
330 "non-canonical specialization?")((void)0);
331 }
332
333 if (ASTMutationListener *L = getASTMutationListener())
334 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
335 SETraits::getDecl(Entry));
336}
337
338//===----------------------------------------------------------------------===//
339// FunctionTemplateDecl Implementation
340//===----------------------------------------------------------------------===//
341
342FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
343 DeclContext *DC,
344 SourceLocation L,
345 DeclarationName Name,
346 TemplateParameterList *Params,
347 NamedDecl *Decl) {
348 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
349 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
350}
351
352FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
353 unsigned ID) {
354 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
355 DeclarationName(), nullptr, nullptr);
356}
357
358RedeclarableTemplateDecl::CommonBase *
359FunctionTemplateDecl::newCommon(ASTContext &C) const {
360 auto *CommonPtr = new (C) Common;
361 C.addDestruction(CommonPtr);
362 return CommonPtr;
363}
364
365void FunctionTemplateDecl::LoadLazySpecializations() const {
366 loadLazySpecializationsImpl();
367}
368
369llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
370FunctionTemplateDecl::getSpecializations() const {
371 LoadLazySpecializations();
372 return getCommonPtr()->Specializations;
373}
374
375FunctionDecl *
376FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
377 void *&InsertPos) {
378 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
379}
380
381void FunctionTemplateDecl::addSpecialization(
382 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
383 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
384 InsertPos);
385}
386
387ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
388 TemplateParameterList *Params = getTemplateParameters();
389 Common *CommonPtr = getCommonPtr();
390 if (!CommonPtr->InjectedArgs) {
391 auto &Context = getASTContext();
392 SmallVector<TemplateArgument, 16> TemplateArgs;
393 Context.getInjectedTemplateArgs(Params, TemplateArgs);
394 CommonPtr->InjectedArgs =
395 new (Context) TemplateArgument[TemplateArgs.size()];
396 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
397 CommonPtr->InjectedArgs);
398 }
399
400 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
401}
402
403void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
404 using Base = RedeclarableTemplateDecl;
405
406 // If we haven't created a common pointer yet, then it can just be created
407 // with the usual method.
408 if (!Base::Common)
409 return;
410
411 Common *ThisCommon = static_cast<Common *>(Base::Common);
412 Common *PrevCommon = nullptr;
413 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
414 for (; Prev; Prev = Prev->getPreviousDecl()) {
415 if (Prev->Base::Common) {
416 PrevCommon = static_cast<Common *>(Prev->Base::Common);
417 break;
418 }
419 PreviousDecls.push_back(Prev);
420 }
421
422 // If the previous redecl chain hasn't created a common pointer yet, then just
423 // use this common pointer.
424 if (!PrevCommon) {
425 for (auto *D : PreviousDecls)
426 D->Base::Common = ThisCommon;
427 return;
428 }
429
430 // Ensure we don't leak any important state.
431 assert(ThisCommon->Specializations.size() == 0 &&((void)0)
432 "Can't merge incompatible declarations!")((void)0);
433
434 Base::Common = PrevCommon;
435}
436
437//===----------------------------------------------------------------------===//
438// ClassTemplateDecl Implementation
439//===----------------------------------------------------------------------===//
440
441ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
442 DeclContext *DC,
443 SourceLocation L,
444 DeclarationName Name,
445 TemplateParameterList *Params,
446 NamedDecl *Decl) {
447 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
448
449 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
450}
451
452ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
453 unsigned ID) {
454 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
455 DeclarationName(), nullptr, nullptr);
456}
457
458void ClassTemplateDecl::LoadLazySpecializations() const {
459 loadLazySpecializationsImpl();
460}
461
462llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
463ClassTemplateDecl::getSpecializations() const {
464 LoadLazySpecializations();
465 return getCommonPtr()->Specializations;
466}
467
468llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
469ClassTemplateDecl::getPartialSpecializations() const {
470 LoadLazySpecializations();
471 return getCommonPtr()->PartialSpecializations;
472}
473
474RedeclarableTemplateDecl::CommonBase *
475ClassTemplateDecl::newCommon(ASTContext &C) const {
476 auto *CommonPtr = new (C) Common;
477 C.addDestruction(CommonPtr);
478 return CommonPtr;
479}
480
481ClassTemplateSpecializationDecl *
482ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
483 void *&InsertPos) {
484 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
485}
486
487void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
488 void *InsertPos) {
489 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
490}
491
492ClassTemplatePartialSpecializationDecl *
493ClassTemplateDecl::findPartialSpecialization(
494 ArrayRef<TemplateArgument> Args,
495 TemplateParameterList *TPL, void *&InsertPos) {
496 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
497 TPL);
498}
499
500static void ProfileTemplateParameterList(ASTContext &C,
501 llvm::FoldingSetNodeID &ID, const TemplateParameterList *TPL) {
502 const Expr *RC = TPL->getRequiresClause();
503 ID.AddBoolean(RC != nullptr);
504 if (RC)
505 RC->Profile(ID, C, /*Canonical=*/true);
506 ID.AddInteger(TPL->size());
507 for (NamedDecl *D : *TPL) {
508 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
509 ID.AddInteger(0);
510 ID.AddBoolean(NTTP->isParameterPack());
511 NTTP->getType().getCanonicalType().Profile(ID);
512 continue;
513 }
514 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
515 ID.AddInteger(1);
516 ID.AddBoolean(TTP->isParameterPack());
517 ID.AddBoolean(TTP->hasTypeConstraint());
518 if (const TypeConstraint *TC = TTP->getTypeConstraint())
519 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
520 /*Canonical=*/true);
521 continue;
522 }
523 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
524 ID.AddInteger(2);
525 ID.AddBoolean(TTP->isParameterPack());
526 ProfileTemplateParameterList(C, ID, TTP->getTemplateParameters());
527 }
528}
529
530void
531ClassTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
532 ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
533 ASTContext &Context) {
534 ID.AddInteger(TemplateArgs.size());
535 for (const TemplateArgument &TemplateArg : TemplateArgs)
536 TemplateArg.Profile(ID, Context);
537 ProfileTemplateParameterList(Context, ID, TPL);
538}
539
540void ClassTemplateDecl::AddPartialSpecialization(
541 ClassTemplatePartialSpecializationDecl *D,
542 void *InsertPos) {
543 if (InsertPos)
544 getPartialSpecializations().InsertNode(D, InsertPos);
545 else {
546 ClassTemplatePartialSpecializationDecl *Existing
547 = getPartialSpecializations().GetOrInsertNode(D);
548 (void)Existing;
549 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?")((void)0);
550 }
551
552 if (ASTMutationListener *L = getASTMutationListener())
553 L->AddedCXXTemplateSpecialization(this, D);
554}
555
556void ClassTemplateDecl::getPartialSpecializations(
557 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {
558 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
559 = getPartialSpecializations();
560 PS.clear();
561 PS.reserve(PartialSpecs.size());
562 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
563 PS.push_back(P.getMostRecentDecl());
564}
565
566ClassTemplatePartialSpecializationDecl *
567ClassTemplateDecl::findPartialSpecialization(QualType T) {
568 ASTContext &Context = getASTContext();
569 for (ClassTemplatePartialSpecializationDecl &P :
570 getPartialSpecializations()) {
571 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
572 return P.getMostRecentDecl();
573 }
574
575 return nullptr;
576}
577
578ClassTemplatePartialSpecializationDecl *
579ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
580 ClassTemplatePartialSpecializationDecl *D) {
581 Decl *DCanon = D->getCanonicalDecl();
582 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
583 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
584 return P.getMostRecentDecl();
585 }
586
587 return nullptr;
588}
589
590QualType
591ClassTemplateDecl::getInjectedClassNameSpecialization() {
592 Common *CommonPtr = getCommonPtr();
593 if (!CommonPtr->InjectedClassNameType.isNull())
594 return CommonPtr->InjectedClassNameType;
595
596 // C++0x [temp.dep.type]p2:
597 // The template argument list of a primary template is a template argument
598 // list in which the nth template argument has the value of the nth template
599 // parameter of the class template. If the nth template parameter is a
600 // template parameter pack (14.5.3), the nth template argument is a pack
601 // expansion (14.5.3) whose pattern is the name of the template parameter
602 // pack.
603 ASTContext &Context = getASTContext();
604 TemplateParameterList *Params = getTemplateParameters();
605 SmallVector<TemplateArgument, 16> TemplateArgs;
606 Context.getInjectedTemplateArgs(Params, TemplateArgs);
607 CommonPtr->InjectedClassNameType
608 = Context.getTemplateSpecializationType(TemplateName(this),
609 TemplateArgs);
610 return CommonPtr->InjectedClassNameType;
611}
612
613//===----------------------------------------------------------------------===//
614// TemplateTypeParm Allocation/Deallocation Method Implementations
615//===----------------------------------------------------------------------===//
616
617TemplateTypeParmDecl *
618TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
619 SourceLocation KeyLoc, SourceLocation NameLoc,
620 unsigned D, unsigned P, IdentifierInfo *Id,
621 bool Typename, bool ParameterPack,
622 bool HasTypeConstraint,
623 Optional<unsigned> NumExpanded) {
624 auto *TTPDecl =
625 new (C, DC,
626 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
627 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
628 HasTypeConstraint, NumExpanded);
629 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
630 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
631 return TTPDecl;
632}
633
634TemplateTypeParmDecl *
635TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
636 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
637 SourceLocation(), nullptr, false,
638 false, None);
639}
640
641TemplateTypeParmDecl *
642TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID,
643 bool HasTypeConstraint) {
644 return new (C, ID,
645 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
646 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(),
647 nullptr, false, HasTypeConstraint, None);
648}
649
650SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
651 return hasDefaultArgument()
652 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
653 : SourceLocation();
654}
655
656SourceRange TemplateTypeParmDecl::getSourceRange() const {
657 if (hasDefaultArgument() && !defaultArgumentWasInherited())
658 return SourceRange(getBeginLoc(),
659 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
660 // TypeDecl::getSourceRange returns a range containing name location, which is
661 // wrong for unnamed template parameters. e.g:
662 // it will return <[[typename>]] instead of <[[typename]]>
663 else if (getDeclName().isEmpty())
664 return SourceRange(getBeginLoc());
665 return TypeDecl::getSourceRange();
666}
667
668unsigned TemplateTypeParmDecl::getDepth() const {
669 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
670}
671
672unsigned TemplateTypeParmDecl::getIndex() const {
673 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
674}
675
676bool TemplateTypeParmDecl::isParameterPack() const {
677 return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
678}
679
680void TemplateTypeParmDecl::setTypeConstraint(NestedNameSpecifierLoc NNS,
681 DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD,
682 const ASTTemplateArgumentListInfo *ArgsAsWritten,
683 Expr *ImmediatelyDeclaredConstraint) {
684 assert(HasTypeConstraint &&((void)0)
685 "HasTypeConstraint=true must be passed at construction in order to "((void)0)
686 "call setTypeConstraint")((void)0);
687 assert(!TypeConstraintInitialized &&((void)0)
688 "TypeConstraint was already initialized!")((void)0);
689 new (getTrailingObjects<TypeConstraint>()) TypeConstraint(NNS, NameInfo,
690 FoundDecl, CD, ArgsAsWritten, ImmediatelyDeclaredConstraint);
691 TypeConstraintInitialized = true;
692}
693
694//===----------------------------------------------------------------------===//
695// NonTypeTemplateParmDecl Method Implementations
696//===----------------------------------------------------------------------===//
697
698NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
699 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
700 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
701 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
702 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
703 TemplateParmPosition(D, P), ParameterPack(true),
704 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
705 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
706 auto TypesAndInfos =
707 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
708 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
709 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
710 TypesAndInfos[I].second = ExpandedTInfos[I];
711 }
712 }
713}
714
715NonTypeTemplateParmDecl *
716NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
717 SourceLocation StartLoc, SourceLocation IdLoc,
718 unsigned D, unsigned P, IdentifierInfo *Id,
719 QualType T, bool ParameterPack,
720 TypeSourceInfo *TInfo) {
721 AutoType *AT =
722 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
723 return new (C, DC,
724 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
725 Expr *>(0,
726 AT && AT->isConstrained() ? 1 : 0))
727 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
728 TInfo);
729}
730
731NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
732 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
733 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
734 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
735 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
736 AutoType *AT = TInfo->getType()->getContainedAutoType();
737 return new (C, DC,
738 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
739 Expr *>(
740 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
741 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
742 ExpandedTypes, ExpandedTInfos);
743}
744
745NonTypeTemplateParmDecl *
746NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
747 bool HasTypeConstraint) {
748 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
749 TypeSourceInfo *>,
750 Expr *>(0,
751 HasTypeConstraint ? 1 : 0))
752 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
753 0, 0, nullptr, QualType(), false, nullptr);
754}
755
756NonTypeTemplateParmDecl *
757NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
758 unsigned NumExpandedTypes,
759 bool HasTypeConstraint) {
760 auto *NTTP =
761 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
762 Expr *>(
763 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
764 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
765 0, 0, nullptr, QualType(), nullptr, None,
766 None);
767 NTTP->NumExpandedTypes = NumExpandedTypes;
768 return NTTP;
769}
770
771SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
772 if (hasDefaultArgument() && !defaultArgumentWasInherited())
773 return SourceRange(getOuterLocStart(),
774 getDefaultArgument()->getSourceRange().getEnd());
775 return DeclaratorDecl::getSourceRange();
776}
777
778SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
779 return hasDefaultArgument()
780 ? getDefaultArgument()->getSourceRange().getBegin()
781 : SourceLocation();
782}
783
784//===----------------------------------------------------------------------===//
785// TemplateTemplateParmDecl Method Implementations
786//===----------------------------------------------------------------------===//
787
788void TemplateTemplateParmDecl::anchor() {}
789
790TemplateTemplateParmDecl::TemplateTemplateParmDecl(
791 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
792 IdentifierInfo *Id, TemplateParameterList *Params,
793 ArrayRef<TemplateParameterList *> Expansions)
794 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
795 TemplateParmPosition(D, P), ParameterPack(true),
796 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
797 if (!Expansions.empty())
798 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
799 getTrailingObjects<TemplateParameterList *>());
800}
801
802TemplateTemplateParmDecl *
803TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
804 SourceLocation L, unsigned D, unsigned P,
805 bool ParameterPack, IdentifierInfo *Id,
806 TemplateParameterList *Params) {
807 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
808 Params);
809}
810
811TemplateTemplateParmDecl *
812TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
813 SourceLocation L, unsigned D, unsigned P,
814 IdentifierInfo *Id,
815 TemplateParameterList *Params,
816 ArrayRef<TemplateParameterList *> Expansions) {
817 return new (C, DC,
818 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
819 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
820}
821
822TemplateTemplateParmDecl *
823TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
824 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
825 false, nullptr, nullptr);
826}
827
828TemplateTemplateParmDecl *
829TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
830 unsigned NumExpansions) {
831 auto *TTP =
832 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
833 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
834 nullptr, None);
835 TTP->NumExpandedParams = NumExpansions;
836 return TTP;
837}
838
839SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
840 return hasDefaultArgument() ? getDefaultArgument().getLocation()
841 : SourceLocation();
842}
843
844void TemplateTemplateParmDecl::setDefaultArgument(
845 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
846 if (DefArg.getArgument().isNull())
847 DefaultArgument.set(nullptr);
848 else
849 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
850}
851
852//===----------------------------------------------------------------------===//
853// TemplateArgumentList Implementation
854//===----------------------------------------------------------------------===//
855TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
856 : Arguments(getTrailingObjects<TemplateArgument>()),
857 NumArguments(Args.size()) {
858 std::uninitialized_copy(Args.begin(), Args.end(),
859 getTrailingObjects<TemplateArgument>());
860}
861
862TemplateArgumentList *
863TemplateArgumentList::CreateCopy(ASTContext &Context,
864 ArrayRef<TemplateArgument> Args) {
865 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
866 return new (Mem) TemplateArgumentList(Args);
867}
868
869FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
870 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
871 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
872 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
873 MemberSpecializationInfo *MSInfo) {
874 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
875 if (TemplateArgsAsWritten)
876 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
877 *TemplateArgsAsWritten);
878
879 void *Mem =
880 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
881 return new (Mem) FunctionTemplateSpecializationInfo(
882 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
883}
884
885//===----------------------------------------------------------------------===//
886// ClassTemplateSpecializationDecl Implementation
887//===----------------------------------------------------------------------===//
888
889ClassTemplateSpecializationDecl::
890ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
891 DeclContext *DC, SourceLocation StartLoc,
892 SourceLocation IdLoc,
893 ClassTemplateDecl *SpecializedTemplate,
894 ArrayRef<TemplateArgument> Args,
895 ClassTemplateSpecializationDecl *PrevDecl)
896 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
897 SpecializedTemplate->getIdentifier(), PrevDecl),
898 SpecializedTemplate(SpecializedTemplate),
899 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
900 SpecializationKind(TSK_Undeclared) {
901}
902
903ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
904 Kind DK)
905 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
906 SourceLocation(), nullptr, nullptr),
907 SpecializationKind(TSK_Undeclared) {}
908
909ClassTemplateSpecializationDecl *
910ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
911 DeclContext *DC,
912 SourceLocation StartLoc,
913 SourceLocation IdLoc,
914 ClassTemplateDecl *SpecializedTemplate,
915 ArrayRef<TemplateArgument> Args,
916 ClassTemplateSpecializationDecl *PrevDecl) {
917 auto *Result =
918 new (Context, DC) ClassTemplateSpecializationDecl(
919 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
920 SpecializedTemplate, Args, PrevDecl);
921 Result->setMayHaveOutOfDateDef(false);
922
923 Context.getTypeDeclType(Result, PrevDecl);
924 return Result;
925}
926
927ClassTemplateSpecializationDecl *
928ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
929 unsigned ID) {
930 auto *Result =
931 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
932 Result->setMayHaveOutOfDateDef(false);
933 return Result;
934}
935
936void ClassTemplateSpecializationDecl::getNameForDiagnostic(
937 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
938 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
939
940 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
941 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
942 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
943 printTemplateArgumentList(
944 OS, ArgsAsWritten->arguments(), Policy,
945 getSpecializedTemplate()->getTemplateParameters());
946 } else {
947 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
948 printTemplateArgumentList(
949 OS, TemplateArgs.asArray(), Policy,
950 getSpecializedTemplate()->getTemplateParameters());
951 }
952}
953
954ClassTemplateDecl *
955ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
956 if (const auto *PartialSpec =
957 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
958 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
959 return SpecializedTemplate.get<ClassTemplateDecl*>();
960}
961
962SourceRange
963ClassTemplateSpecializationDecl::getSourceRange() const {
964 if (ExplicitInfo) {
965 SourceLocation Begin = getTemplateKeywordLoc();
966 if (Begin.isValid()) {
967 // Here we have an explicit (partial) specialization or instantiation.
968 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||((void)0)
969 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||((void)0)
970 getSpecializationKind() == TSK_ExplicitInstantiationDefinition)((void)0);
971 if (getExternLoc().isValid())
972 Begin = getExternLoc();
973 SourceLocation End = getBraceRange().getEnd();
974 if (End.isInvalid())
975 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
976 return SourceRange(Begin, End);
977 }
978 // An implicit instantiation of a class template partial specialization
979 // uses ExplicitInfo to record the TypeAsWritten, but the source
980 // locations should be retrieved from the instantiation pattern.
981 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
982 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
983 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
984 assert(inst_from != nullptr)((void)0);
985 return inst_from->getSourceRange();
986 }
987 else {
988 // No explicit info available.
989 llvm::PointerUnion<ClassTemplateDecl *,
990 ClassTemplatePartialSpecializationDecl *>
991 inst_from = getInstantiatedFrom();
992 if (inst_from.isNull())
993 return getSpecializedTemplate()->getSourceRange();
994 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
995 return ctd->getSourceRange();
996 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
997 ->getSourceRange();
998 }
999}
1000
1001//===----------------------------------------------------------------------===//
1002// ConceptDecl Implementation
1003//===----------------------------------------------------------------------===//
1004ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1005 SourceLocation L, DeclarationName Name,
1006 TemplateParameterList *Params,
1007 Expr *ConstraintExpr) {
1008 AdoptTemplateParameterList(Params, DC);
1009 return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1010}
1011
1012ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
1013 unsigned ID) {
1014 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1015 DeclarationName(),
1016 nullptr, nullptr);
1017
1018 return Result;
1019}
1020
1021//===----------------------------------------------------------------------===//
1022// ClassTemplatePartialSpecializationDecl Implementation
1023//===----------------------------------------------------------------------===//
1024void ClassTemplatePartialSpecializationDecl::anchor() {}
1025
1026ClassTemplatePartialSpecializationDecl::
1027ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1028 DeclContext *DC,
1029 SourceLocation StartLoc,
1030 SourceLocation IdLoc,
1031 TemplateParameterList *Params,
1032 ClassTemplateDecl *SpecializedTemplate,
1033 ArrayRef<TemplateArgument> Args,
1034 const ASTTemplateArgumentListInfo *ArgInfos,
1035 ClassTemplatePartialSpecializationDecl *PrevDecl)
1036 : ClassTemplateSpecializationDecl(Context,
1037 ClassTemplatePartialSpecialization,
1038 TK, DC, StartLoc, IdLoc,
1039 SpecializedTemplate, Args, PrevDecl),
1040 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1041 InstantiatedFromMember(nullptr, false) {
1042 AdoptTemplateParameterList(Params, this);
1043}
1044
1045ClassTemplatePartialSpecializationDecl *
1046ClassTemplatePartialSpecializationDecl::
1047Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1048 SourceLocation StartLoc, SourceLocation IdLoc,
1049 TemplateParameterList *Params,
1050 ClassTemplateDecl *SpecializedTemplate,
1051 ArrayRef<TemplateArgument> Args,
1052 const TemplateArgumentListInfo &ArgInfos,
1053 QualType CanonInjectedType,
1054 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1055 const ASTTemplateArgumentListInfo *ASTArgInfos =
1056 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1057
1058 auto *Result = new (Context, DC)
1059 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
1060 Params, SpecializedTemplate, Args,
1061 ASTArgInfos, PrevDecl);
1062 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1063 Result->setMayHaveOutOfDateDef(false);
1064
1065 Context.getInjectedClassNameType(Result, CanonInjectedType);
1066 return Result;
1067}
1068
1069ClassTemplatePartialSpecializationDecl *
1070ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1071 unsigned ID) {
1072 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1073 Result->setMayHaveOutOfDateDef(false);
1074 return Result;
1075}
1076
1077//===----------------------------------------------------------------------===//
1078// FriendTemplateDecl Implementation
1079//===----------------------------------------------------------------------===//
1080
1081void FriendTemplateDecl::anchor() {}
1082
1083FriendTemplateDecl *
1084FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1085 SourceLocation L,
1086 MutableArrayRef<TemplateParameterList *> Params,
1087 FriendUnion Friend, SourceLocation FLoc) {
1088 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
1089}
1090
1091FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1092 unsigned ID) {
1093 return new (C, ID) FriendTemplateDecl(EmptyShell());
1094}
1095
1096//===----------------------------------------------------------------------===//
1097// TypeAliasTemplateDecl Implementation
1098//===----------------------------------------------------------------------===//
1099
1100TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
1101 DeclContext *DC,
1102 SourceLocation L,
1103 DeclarationName Name,
1104 TemplateParameterList *Params,
1105 NamedDecl *Decl) {
1106 AdoptTemplateParameterList(Params, DC);
1107 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1108}
1109
1110TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
1111 unsigned ID) {
1112 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1113 DeclarationName(), nullptr, nullptr);
1114}
1115
1116RedeclarableTemplateDecl::CommonBase *
1117TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1118 auto *CommonPtr = new (C) Common;
1119 C.addDestruction(CommonPtr);
1120 return CommonPtr;
1121}
1122
1123//===----------------------------------------------------------------------===//
1124// ClassScopeFunctionSpecializationDecl Implementation
1125//===----------------------------------------------------------------------===//
1126
1127void ClassScopeFunctionSpecializationDecl::anchor() {}
1128
1129ClassScopeFunctionSpecializationDecl *
1130ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
1131 unsigned ID) {
1132 return new (C, ID) ClassScopeFunctionSpecializationDecl(
1133 nullptr, SourceLocation(), nullptr, nullptr);
1134}
1135
1136//===----------------------------------------------------------------------===//
1137// VarTemplateDecl Implementation
1138//===----------------------------------------------------------------------===//
1139
1140VarTemplateDecl *VarTemplateDecl::getDefinition() {
1141 VarTemplateDecl *CurD = this;
1142 while (CurD) {
1143 if (CurD->isThisDeclarationADefinition())
1144 return CurD;
1145 CurD = CurD->getPreviousDecl();
1146 }
1147 return nullptr;
1148}
1149
1150VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1151 SourceLocation L, DeclarationName Name,
1152 TemplateParameterList *Params,
1153 VarDecl *Decl) {
1154 AdoptTemplateParameterList(Params, DC);
1155 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1156}
1157
1158VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1159 unsigned ID) {
1160 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1161 DeclarationName(), nullptr, nullptr);
1162}
1163
1164void VarTemplateDecl::LoadLazySpecializations() const {
1165 loadLazySpecializationsImpl();
1166}
1167
1168llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1169VarTemplateDecl::getSpecializations() const {
1170 LoadLazySpecializations();
1171 return getCommonPtr()->Specializations;
1172}
1173
1174llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1175VarTemplateDecl::getPartialSpecializations() const {
1176 LoadLazySpecializations();
1177 return getCommonPtr()->PartialSpecializations;
1178}
1179
1180RedeclarableTemplateDecl::CommonBase *
1181VarTemplateDecl::newCommon(ASTContext &C) const {
1182 auto *CommonPtr = new (C) Common;
1183 C.addDestruction(CommonPtr);
1184 return CommonPtr;
1185}
1186
1187VarTemplateSpecializationDecl *
1188VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1189 void *&InsertPos) {
1190 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1191}
1192
1193void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1194 void *InsertPos) {
1195 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1196}
1197
1198VarTemplatePartialSpecializationDecl *
1199VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1200 TemplateParameterList *TPL, void *&InsertPos) {
1201 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1202 TPL);
1203}
1204
1205void
1206VarTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
1207 ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
1208 ASTContext &Context) {
1209 ID.AddInteger(TemplateArgs.size());
1210 for (const TemplateArgument &TemplateArg : TemplateArgs)
1211 TemplateArg.Profile(ID, Context);
1212 ProfileTemplateParameterList(Context, ID, TPL);
1213}
1214
1215void VarTemplateDecl::AddPartialSpecialization(
1216 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1217 if (InsertPos)
1218 getPartialSpecializations().InsertNode(D, InsertPos);
1219 else {
1220 VarTemplatePartialSpecializationDecl *Existing =
1221 getPartialSpecializations().GetOrInsertNode(D);
1222 (void)Existing;
1223 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?")((void)0);
1224 }
1225
1226 if (ASTMutationListener *L = getASTMutationListener())
1227 L->AddedCXXTemplateSpecialization(this, D);
1228}
1229
1230void VarTemplateDecl::getPartialSpecializations(
1231 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1232 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1233 getPartialSpecializations();
1234 PS.clear();
1235 PS.reserve(PartialSpecs.size());
1236 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1237 PS.push_back(P.getMostRecentDecl());
1238}
1239
1240VarTemplatePartialSpecializationDecl *
1241VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1242 VarTemplatePartialSpecializationDecl *D) {
1243 Decl *DCanon = D->getCanonicalDecl();
1244 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1245 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1246 return P.getMostRecentDecl();
1247 }
1248
1249 return nullptr;
1250}
1251
1252//===----------------------------------------------------------------------===//
1253// VarTemplateSpecializationDecl Implementation
1254//===----------------------------------------------------------------------===//
1255
1256VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1257 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1258 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1259 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1260 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1261 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1262 SpecializedTemplate(SpecializedTemplate),
1263 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1264 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1265
1266VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1267 ASTContext &C)
1268 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1269 QualType(), nullptr, SC_None),
1270 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1271
1272VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1273 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1274 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1275 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1276 return new (Context, DC) VarTemplateSpecializationDecl(
1277 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1278 SpecializedTemplate, T, TInfo, S, Args);
1279}
1280
1281VarTemplateSpecializationDecl *
1282VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1283 return new (C, ID)
1284 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1285}
1286
1287void VarTemplateSpecializationDecl::getNameForDiagnostic(
1288 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1289 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1290
1291 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1292 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1293 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1294 printTemplateArgumentList(
1295 OS, ArgsAsWritten->arguments(), Policy,
1296 getSpecializedTemplate()->getTemplateParameters());
1297 } else {
1298 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1299 printTemplateArgumentList(
1300 OS, TemplateArgs.asArray(), Policy,
1301 getSpecializedTemplate()->getTemplateParameters());
1302 }
1303}
1304
1305VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1306 if (const auto *PartialSpec =
1307 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1308 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1309 return SpecializedTemplate.get<VarTemplateDecl *>();
1310}
1311
1312void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1313 const TemplateArgumentListInfo &ArgsInfo) {
1314 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1315 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1316 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1317 TemplateArgsInfo.addArgument(Loc);
1318}
1319
1320//===----------------------------------------------------------------------===//
1321// VarTemplatePartialSpecializationDecl Implementation
1322//===----------------------------------------------------------------------===//
1323
1324void VarTemplatePartialSpecializationDecl::anchor() {}
1325
1326VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1327 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1328 SourceLocation IdLoc, TemplateParameterList *Params,
1329 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1330 StorageClass S, ArrayRef<TemplateArgument> Args,
1331 const ASTTemplateArgumentListInfo *ArgInfos)
1332 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1333 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1334 TInfo, S, Args),
1335 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1336 InstantiatedFromMember(nullptr, false) {
1337 // TODO: The template parameters should be in DC by now. Verify.
1338 // AdoptTemplateParameterList(Params, DC);
1339}
1340
1341VarTemplatePartialSpecializationDecl *
1342VarTemplatePartialSpecializationDecl::Create(
1343 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1344 SourceLocation IdLoc, TemplateParameterList *Params,
1345 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1346 StorageClass S, ArrayRef<TemplateArgument> Args,
1347 const TemplateArgumentListInfo &ArgInfos) {
1348 const ASTTemplateArgumentListInfo *ASTArgInfos
1349 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1350
1351 auto *Result =
1352 new (Context, DC) VarTemplatePartialSpecializationDecl(
1353 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1354 S, Args, ASTArgInfos);
1355 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1356 return Result;
1357}
1358
1359VarTemplatePartialSpecializationDecl *
1360VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1361 unsigned ID) {
1362 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1363}
1364
1365static TemplateParameterList *
1366createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1367 // typename T
1368 auto *T = TemplateTypeParmDecl::Create(
1369 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1370 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1371 /*HasTypeConstraint=*/false);
1372 T->setImplicit(true);
1373
1374 // T ...Ints
1375 TypeSourceInfo *TI =
1376 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1377 auto *N = NonTypeTemplateParmDecl::Create(
1378 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1379 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1380 N->setImplicit(true);
1381
1382 // <typename T, T ...Ints>
1383 NamedDecl *P[2] = {T, N};
1384 auto *TPL = TemplateParameterList::Create(
1385 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1386
1387 // template <typename T, ...Ints> class IntSeq
1388 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1389 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1390 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1391 TemplateTemplateParm->setImplicit(true);
1392
1393 // typename T
1394 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1395 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1396 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1397 /*HasTypeConstraint=*/false);
1398 TemplateTypeParm->setImplicit(true);
1399
1400 // T N
1401 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1402 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1403 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1404 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1405 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1406 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1407 NonTypeTemplateParm};
1408
1409 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1410 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1411 Params, SourceLocation(), nullptr);
1412}
1413
1414static TemplateParameterList *
1415createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1416 // std::size_t Index
1417 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1418 auto *Index = NonTypeTemplateParmDecl::Create(
1419 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1420 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1421
1422 // typename ...T
1423 auto *Ts = TemplateTypeParmDecl::Create(
1424 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1425 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1426 /*HasTypeConstraint=*/false);
1427 Ts->setImplicit(true);
1428
1429 // template <std::size_t Index, typename ...T>
1430 NamedDecl *Params[] = {Index, Ts};
1431 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
5
Calling 'TemplateParameterList::Create'
1432 llvm::makeArrayRef(Params),
1433 SourceLocation(), nullptr);
4
Passing null pointer value via 6th parameter 'RequiresClause'
1434}
1435
1436static TemplateParameterList *createBuiltinTemplateParameterList(
1437 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1438 switch (BTK) {
2
Control jumps to 'case BTK__type_pack_element:' at line 1441
1439 case BTK__make_integer_seq:
1440 return createMakeIntegerSeqParameterList(C, DC);
1441 case BTK__type_pack_element:
1442 return createTypePackElementParameterList(C, DC);
3
Calling 'createTypePackElementParameterList'
1443 }
1444
1445 llvm_unreachable("unhandled BuiltinTemplateKind!")__builtin_unreachable();
1446}
1447
1448void BuiltinTemplateDecl::anchor() {}
1449
1450BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1451 DeclarationName Name,
1452 BuiltinTemplateKind BTK)
1453 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1454 createBuiltinTemplateParameterList(C, DC, BTK)),
1
Calling 'createBuiltinTemplateParameterList'
1455 BTK(BTK) {}
1456
1457void TypeConstraint::print(llvm::raw_ostream &OS, PrintingPolicy Policy) const {
1458 if (NestedNameSpec)
1459 NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy);
1460 ConceptName.printName(OS, Policy);
1461 if (hasExplicitTemplateArgs()) {
1462 OS << "<";
1463 // FIXME: Find corresponding parameter for argument
1464 for (auto &ArgLoc : ArgsAsWritten->arguments())
1465 ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
1466 OS << ">";
1467 }
1468}
1469
1470TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1471 QualType T,
1472 const APValue &V) {
1473 DeclContext *DC = C.getTranslationUnitDecl();
1474 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1475 C.addDestruction(&TPOD->Value);
1476 return TPOD;
1477}
1478
1479TemplateParamObjectDecl *
1480TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1481 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1482 C.addDestruction(&TPOD->Value);
1483 return TPOD;
1484}
1485
1486void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS) const {
1487 OS << "<template param ";
1488 printAsExpr(OS);
1489 OS << ">";
1490}
1491
1492void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1493 const ASTContext &Ctx = getASTContext();
1494 getType().getUnqualifiedType().print(OS, Ctx.getPrintingPolicy());
1495 printAsInit(OS);
1496}
1497
1498void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1499 const ASTContext &Ctx = getASTContext();
1500 getValue().printPretty(OS, Ctx, getType());
1501}