Bug Summary

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