Bug Summary

File:tools/clang/lib/AST/DeclTemplate.cpp
Warning:line 526, column 10
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-10~svn373517/build-llvm/tools/clang/lib/AST -I /build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST -I /build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include -I /build/llvm-toolchain-snapshot-10~svn373517/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-10~svn373517/build-llvm/include -I /build/llvm-toolchain-snapshot-10~svn373517/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-10~svn373517/build-llvm/tools/clang/lib/AST -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~svn373517=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2019-10-02-234743-9763-1 -x c++ /build/llvm-toolchain-snapshot-10~svn373517/tools/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
46TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
47 SourceLocation LAngleLoc,
48 ArrayRef<NamedDecl *> Params,
49 SourceLocation RAngleLoc,
50 Expr *RequiresClause)
51 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
52 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
53 HasRequiresClause(static_cast<bool>(RequiresClause)) {
54 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
55 NamedDecl *P = Params[Idx];
56 begin()[Idx] = P;
57
58 if (!P->isTemplateParameterPack()) {
59 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
60 if (NTTP->getType()->containsUnexpandedParameterPack())
61 ContainsUnexpandedParameterPack = true;
62
63 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
64 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
65 ContainsUnexpandedParameterPack = true;
66
67 // FIXME: If a default argument contains an unexpanded parameter pack, the
68 // template parameter list does too.
69 }
70 }
71 if (RequiresClause) {
72 *getTrailingObjects<Expr *>() = RequiresClause;
73 }
74}
75
76TemplateParameterList *
77TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
78 SourceLocation LAngleLoc,
79 ArrayRef<NamedDecl *> Params,
80 SourceLocation RAngleLoc, Expr *RequiresClause) {
81 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
82 Params.size(), RequiresClause ? 1u : 0u),
83 alignof(TemplateParameterList));
84 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
85 RAngleLoc, RequiresClause);
86}
87
88unsigned TemplateParameterList::getMinRequiredArguments() const {
89 unsigned NumRequiredArgs = 0;
90 for (const NamedDecl *P : asArray()) {
91 if (P->isTemplateParameterPack()) {
92 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
93 if (NTTP->isExpandedParameterPack()) {
94 NumRequiredArgs += NTTP->getNumExpansionTypes();
95 continue;
96 }
97
98 break;
99 }
100
101 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
102 if (TTP->hasDefaultArgument())
103 break;
104 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
105 if (NTTP->hasDefaultArgument())
106 break;
107 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
108 break;
109
110 ++NumRequiredArgs;
111 }
112
113 return NumRequiredArgs;
114}
115
116unsigned TemplateParameterList::getDepth() const {
117 if (size() == 0)
118 return 0;
119
120 const NamedDecl *FirstParm = getParam(0);
121 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
122 return TTP->getDepth();
123 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
124 return NTTP->getDepth();
125 else
126 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
127}
128
129static void AdoptTemplateParameterList(TemplateParameterList *Params,
130 DeclContext *Owner) {
131 for (NamedDecl *P : *Params) {
132 P->setDeclContext(Owner);
133
134 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
135 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
136 }
137}
138
139namespace clang {
140
141void *allocateDefaultArgStorageChain(const ASTContext &C) {
142 return new (C) char[sizeof(void*) * 2];
143}
144
145} // namespace clang
146
147//===----------------------------------------------------------------------===//
148// RedeclarableTemplateDecl Implementation
149//===----------------------------------------------------------------------===//
150
151void RedeclarableTemplateDecl::anchor() {}
152
153RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
154 if (Common)
155 return Common;
156
157 // Walk the previous-declaration chain until we either find a declaration
158 // with a common pointer or we run out of previous declarations.
159 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
160 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
161 Prev = Prev->getPreviousDecl()) {
162 if (Prev->Common) {
163 Common = Prev->Common;
164 break;
165 }
166
167 PrevDecls.push_back(Prev);
168 }
169
170 // If we never found a common pointer, allocate one now.
171 if (!Common) {
172 // FIXME: If any of the declarations is from an AST file, we probably
173 // need an update record to add the common data.
174
175 Common = newCommon(getASTContext());
176 }
177
178 // Update any previous declarations we saw with the common pointer.
179 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
180 Prev->Common = Common;
181
182 return Common;
183}
184
185void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
186 // Grab the most recent declaration to ensure we've loaded any lazy
187 // redeclarations of this template.
188 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
189 if (CommonBasePtr->LazySpecializations) {
190 ASTContext &Context = getASTContext();
191 uint32_t *Specs = CommonBasePtr->LazySpecializations;
192 CommonBasePtr->LazySpecializations = nullptr;
193 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
194 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
195 }
196}
197
198template<class EntryType>
199typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
200RedeclarableTemplateDecl::findSpecializationImpl(
201 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
202 void *&InsertPos) {
203 using SETraits = SpecEntryTraits<EntryType>;
204
205 llvm::FoldingSetNodeID ID;
206 EntryType::Profile(ID, Args, getASTContext());
207 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
208 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
209}
210
211template<class Derived, class EntryType>
212void RedeclarableTemplateDecl::addSpecializationImpl(
213 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
214 void *InsertPos) {
215 using SETraits = SpecEntryTraits<EntryType>;
216
217 if (InsertPos) {
218#ifndef NDEBUG
219 void *CorrectInsertPos;
220 assert(!findSpecializationImpl(Specializations,((!findSpecializationImpl(Specializations, SETraits::getTemplateArgs
(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos
&& "given incorrect InsertPos for specialization") ?
static_cast<void> (0) : __assert_fail ("!findSpecializationImpl(Specializations, SETraits::getTemplateArgs(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos && \"given incorrect InsertPos for specialization\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 224, __PRETTY_FUNCTION__))
221 SETraits::getTemplateArgs(Entry),((!findSpecializationImpl(Specializations, SETraits::getTemplateArgs
(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos
&& "given incorrect InsertPos for specialization") ?
static_cast<void> (0) : __assert_fail ("!findSpecializationImpl(Specializations, SETraits::getTemplateArgs(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos && \"given incorrect InsertPos for specialization\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 224, __PRETTY_FUNCTION__))
222 CorrectInsertPos) &&((!findSpecializationImpl(Specializations, SETraits::getTemplateArgs
(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos
&& "given incorrect InsertPos for specialization") ?
static_cast<void> (0) : __assert_fail ("!findSpecializationImpl(Specializations, SETraits::getTemplateArgs(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos && \"given incorrect InsertPos for specialization\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 224, __PRETTY_FUNCTION__))
223 InsertPos == CorrectInsertPos &&((!findSpecializationImpl(Specializations, SETraits::getTemplateArgs
(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos
&& "given incorrect InsertPos for specialization") ?
static_cast<void> (0) : __assert_fail ("!findSpecializationImpl(Specializations, SETraits::getTemplateArgs(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos && \"given incorrect InsertPos for specialization\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 224, __PRETTY_FUNCTION__))
224 "given incorrect InsertPos for specialization")((!findSpecializationImpl(Specializations, SETraits::getTemplateArgs
(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos
&& "given incorrect InsertPos for specialization") ?
static_cast<void> (0) : __assert_fail ("!findSpecializationImpl(Specializations, SETraits::getTemplateArgs(Entry), CorrectInsertPos) && InsertPos == CorrectInsertPos && \"given incorrect InsertPos for specialization\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 224, __PRETTY_FUNCTION__))
;
225#endif
226 Specializations.InsertNode(Entry, InsertPos);
227 } else {
228 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
229 (void)Existing;
230 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&((SETraits::getDecl(Existing)->isCanonicalDecl() &&
"non-canonical specialization?") ? static_cast<void> (
0) : __assert_fail ("SETraits::getDecl(Existing)->isCanonicalDecl() && \"non-canonical specialization?\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 231, __PRETTY_FUNCTION__))
231 "non-canonical specialization?")((SETraits::getDecl(Existing)->isCanonicalDecl() &&
"non-canonical specialization?") ? static_cast<void> (
0) : __assert_fail ("SETraits::getDecl(Existing)->isCanonicalDecl() && \"non-canonical specialization?\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 231, __PRETTY_FUNCTION__))
;
232 }
233
234 if (ASTMutationListener *L = getASTMutationListener())
235 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
236 SETraits::getDecl(Entry));
237}
238
239//===----------------------------------------------------------------------===//
240// FunctionTemplateDecl Implementation
241//===----------------------------------------------------------------------===//
242
243FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
244 DeclContext *DC,
245 SourceLocation L,
246 DeclarationName Name,
247 TemplateParameterList *Params,
248 NamedDecl *Decl) {
249 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
250 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
251}
252
253FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
254 unsigned ID) {
255 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
256 DeclarationName(), nullptr, nullptr);
257}
258
259RedeclarableTemplateDecl::CommonBase *
260FunctionTemplateDecl::newCommon(ASTContext &C) const {
261 auto *CommonPtr = new (C) Common;
262 C.addDestruction(CommonPtr);
263 return CommonPtr;
264}
265
266void FunctionTemplateDecl::LoadLazySpecializations() const {
267 loadLazySpecializationsImpl();
268}
269
270llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
271FunctionTemplateDecl::getSpecializations() const {
272 LoadLazySpecializations();
273 return getCommonPtr()->Specializations;
274}
275
276FunctionDecl *
277FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
278 void *&InsertPos) {
279 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
280}
281
282void FunctionTemplateDecl::addSpecialization(
283 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
284 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
285 InsertPos);
286}
287
288ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
289 TemplateParameterList *Params = getTemplateParameters();
290 Common *CommonPtr = getCommonPtr();
291 if (!CommonPtr->InjectedArgs) {
292 auto &Context = getASTContext();
293 SmallVector<TemplateArgument, 16> TemplateArgs;
294 Context.getInjectedTemplateArgs(Params, TemplateArgs);
295 CommonPtr->InjectedArgs =
296 new (Context) TemplateArgument[TemplateArgs.size()];
297 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
298 CommonPtr->InjectedArgs);
299 }
300
301 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
302}
303
304void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
305 using Base = RedeclarableTemplateDecl;
306
307 // If we haven't created a common pointer yet, then it can just be created
308 // with the usual method.
309 if (!Base::Common)
310 return;
311
312 Common *ThisCommon = static_cast<Common *>(Base::Common);
313 Common *PrevCommon = nullptr;
314 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
315 for (; Prev; Prev = Prev->getPreviousDecl()) {
316 if (Prev->Base::Common) {
317 PrevCommon = static_cast<Common *>(Prev->Base::Common);
318 break;
319 }
320 PreviousDecls.push_back(Prev);
321 }
322
323 // If the previous redecl chain hasn't created a common pointer yet, then just
324 // use this common pointer.
325 if (!PrevCommon) {
326 for (auto *D : PreviousDecls)
327 D->Base::Common = ThisCommon;
328 return;
329 }
330
331 // Ensure we don't leak any important state.
332 assert(ThisCommon->Specializations.size() == 0 &&((ThisCommon->Specializations.size() == 0 && "Can't merge incompatible declarations!"
) ? static_cast<void> (0) : __assert_fail ("ThisCommon->Specializations.size() == 0 && \"Can't merge incompatible declarations!\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 333, __PRETTY_FUNCTION__))
333 "Can't merge incompatible declarations!")((ThisCommon->Specializations.size() == 0 && "Can't merge incompatible declarations!"
) ? static_cast<void> (0) : __assert_fail ("ThisCommon->Specializations.size() == 0 && \"Can't merge incompatible declarations!\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 333, __PRETTY_FUNCTION__))
;
334
335 Base::Common = PrevCommon;
336}
337
338//===----------------------------------------------------------------------===//
339// ClassTemplateDecl Implementation
340//===----------------------------------------------------------------------===//
341
342ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
343 DeclContext *DC,
344 SourceLocation L,
345 DeclarationName Name,
346 TemplateParameterList *Params,
347 NamedDecl *Decl,
348 Expr *AssociatedConstraints) {
349 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
350
351 if (!AssociatedConstraints) {
352 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
353 }
354
355 auto *const CTDI = new (C) ConstrainedTemplateDeclInfo;
356 auto *const New =
357 new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
358 New->setAssociatedConstraints(AssociatedConstraints);
359 return New;
360}
361
362ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
363 unsigned ID) {
364 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
365 DeclarationName(), nullptr, nullptr);
366}
367
368void ClassTemplateDecl::LoadLazySpecializations() const {
369 loadLazySpecializationsImpl();
370}
371
372llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
373ClassTemplateDecl::getSpecializations() const {
374 LoadLazySpecializations();
375 return getCommonPtr()->Specializations;
376}
377
378llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
379ClassTemplateDecl::getPartialSpecializations() {
380 LoadLazySpecializations();
381 return getCommonPtr()->PartialSpecializations;
382}
383
384RedeclarableTemplateDecl::CommonBase *
385ClassTemplateDecl::newCommon(ASTContext &C) const {
386 auto *CommonPtr = new (C) Common;
387 C.addDestruction(CommonPtr);
388 return CommonPtr;
389}
390
391ClassTemplateSpecializationDecl *
392ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
393 void *&InsertPos) {
394 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
395}
396
397void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
398 void *InsertPos) {
399 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
400}
401
402ClassTemplatePartialSpecializationDecl *
403ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
404 void *&InsertPos) {
405 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
406}
407
408void ClassTemplateDecl::AddPartialSpecialization(
409 ClassTemplatePartialSpecializationDecl *D,
410 void *InsertPos) {
411 if (InsertPos)
412 getPartialSpecializations().InsertNode(D, InsertPos);
413 else {
414 ClassTemplatePartialSpecializationDecl *Existing
415 = getPartialSpecializations().GetOrInsertNode(D);
416 (void)Existing;
417 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?")((Existing->isCanonicalDecl() && "Non-canonical specialization?"
) ? static_cast<void> (0) : __assert_fail ("Existing->isCanonicalDecl() && \"Non-canonical specialization?\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 417, __PRETTY_FUNCTION__))
;
418 }
419
420 if (ASTMutationListener *L = getASTMutationListener())
421 L->AddedCXXTemplateSpecialization(this, D);
422}
423
424void ClassTemplateDecl::getPartialSpecializations(
425 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
426 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
427 = getPartialSpecializations();
428 PS.clear();
429 PS.reserve(PartialSpecs.size());
430 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
431 PS.push_back(P.getMostRecentDecl());
432}
433
434ClassTemplatePartialSpecializationDecl *
435ClassTemplateDecl::findPartialSpecialization(QualType T) {
436 ASTContext &Context = getASTContext();
437 for (ClassTemplatePartialSpecializationDecl &P :
438 getPartialSpecializations()) {
439 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
440 return P.getMostRecentDecl();
441 }
442
443 return nullptr;
444}
445
446ClassTemplatePartialSpecializationDecl *
447ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
448 ClassTemplatePartialSpecializationDecl *D) {
449 Decl *DCanon = D->getCanonicalDecl();
450 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
451 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
452 return P.getMostRecentDecl();
453 }
454
455 return nullptr;
456}
457
458QualType
459ClassTemplateDecl::getInjectedClassNameSpecialization() {
460 Common *CommonPtr = getCommonPtr();
461 if (!CommonPtr->InjectedClassNameType.isNull())
462 return CommonPtr->InjectedClassNameType;
463
464 // C++0x [temp.dep.type]p2:
465 // The template argument list of a primary template is a template argument
466 // list in which the nth template argument has the value of the nth template
467 // parameter of the class template. If the nth template parameter is a
468 // template parameter pack (14.5.3), the nth template argument is a pack
469 // expansion (14.5.3) whose pattern is the name of the template parameter
470 // pack.
471 ASTContext &Context = getASTContext();
472 TemplateParameterList *Params = getTemplateParameters();
473 SmallVector<TemplateArgument, 16> TemplateArgs;
474 Context.getInjectedTemplateArgs(Params, TemplateArgs);
475 CommonPtr->InjectedClassNameType
476 = Context.getTemplateSpecializationType(TemplateName(this),
477 TemplateArgs);
478 return CommonPtr->InjectedClassNameType;
479}
480
481//===----------------------------------------------------------------------===//
482// TemplateTypeParm Allocation/Deallocation Method Implementations
483//===----------------------------------------------------------------------===//
484
485TemplateTypeParmDecl *
486TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
487 SourceLocation KeyLoc, SourceLocation NameLoc,
488 unsigned D, unsigned P, IdentifierInfo *Id,
489 bool Typename, bool ParameterPack) {
490 auto *TTPDecl =
491 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
492 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
493 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
494 return TTPDecl;
495}
496
497TemplateTypeParmDecl *
498TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
499 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
500 SourceLocation(), nullptr, false);
501}
502
503SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
504 return hasDefaultArgument()
505 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
506 : SourceLocation();
507}
508
509SourceRange TemplateTypeParmDecl::getSourceRange() const {
510 if (hasDefaultArgument() && !defaultArgumentWasInherited())
511 return SourceRange(getBeginLoc(),
512 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
513 // TypeDecl::getSourceRange returns a range containing name location, which is
514 // wrong for unnamed template parameters. e.g:
515 // it will return <[[typename>]] instead of <[[typename]]>
516 else if (getDeclName().isEmpty())
517 return SourceRange(getBeginLoc());
518 return TypeDecl::getSourceRange();
519}
520
521unsigned TemplateTypeParmDecl::getDepth() const {
522 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
523}
524
525unsigned TemplateTypeParmDecl::getIndex() const {
526 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
1
Assuming the object is not a 'TemplateTypeParmType'
2
Called C++ object pointer is null
527}
528
529bool TemplateTypeParmDecl::isParameterPack() const {
530 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
531}
532
533//===----------------------------------------------------------------------===//
534// NonTypeTemplateParmDecl Method Implementations
535//===----------------------------------------------------------------------===//
536
537NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
538 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
539 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
540 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
541 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
542 TemplateParmPosition(D, P), ParameterPack(true),
543 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
544 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
545 auto TypesAndInfos =
546 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
547 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
548 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
549 TypesAndInfos[I].second = ExpandedTInfos[I];
550 }
551 }
552}
553
554NonTypeTemplateParmDecl *
555NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
556 SourceLocation StartLoc, SourceLocation IdLoc,
557 unsigned D, unsigned P, IdentifierInfo *Id,
558 QualType T, bool ParameterPack,
559 TypeSourceInfo *TInfo) {
560 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
561 T, ParameterPack, TInfo);
562}
563
564NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
565 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
566 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
567 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
568 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
569 return new (C, DC,
570 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
571 ExpandedTypes.size()))
572 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
573 ExpandedTypes, ExpandedTInfos);
574}
575
576NonTypeTemplateParmDecl *
577NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
578 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
579 SourceLocation(), 0, 0, nullptr,
580 QualType(), false, nullptr);
581}
582
583NonTypeTemplateParmDecl *
584NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
585 unsigned NumExpandedTypes) {
586 auto *NTTP =
587 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
588 NumExpandedTypes))
589 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
590 0, 0, nullptr, QualType(), nullptr, None,
591 None);
592 NTTP->NumExpandedTypes = NumExpandedTypes;
593 return NTTP;
594}
595
596SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
597 if (hasDefaultArgument() && !defaultArgumentWasInherited())
598 return SourceRange(getOuterLocStart(),
599 getDefaultArgument()->getSourceRange().getEnd());
600 return DeclaratorDecl::getSourceRange();
601}
602
603SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
604 return hasDefaultArgument()
605 ? getDefaultArgument()->getSourceRange().getBegin()
606 : SourceLocation();
607}
608
609//===----------------------------------------------------------------------===//
610// TemplateTemplateParmDecl Method Implementations
611//===----------------------------------------------------------------------===//
612
613void TemplateTemplateParmDecl::anchor() {}
614
615TemplateTemplateParmDecl::TemplateTemplateParmDecl(
616 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
617 IdentifierInfo *Id, TemplateParameterList *Params,
618 ArrayRef<TemplateParameterList *> Expansions)
619 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
620 TemplateParmPosition(D, P), ParameterPack(true),
621 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
622 if (!Expansions.empty())
623 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
624 getTrailingObjects<TemplateParameterList *>());
625}
626
627TemplateTemplateParmDecl *
628TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
629 SourceLocation L, unsigned D, unsigned P,
630 bool ParameterPack, IdentifierInfo *Id,
631 TemplateParameterList *Params) {
632 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
633 Params);
634}
635
636TemplateTemplateParmDecl *
637TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
638 SourceLocation L, unsigned D, unsigned P,
639 IdentifierInfo *Id,
640 TemplateParameterList *Params,
641 ArrayRef<TemplateParameterList *> Expansions) {
642 return new (C, DC,
643 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
644 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
645}
646
647TemplateTemplateParmDecl *
648TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
649 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
650 false, nullptr, nullptr);
651}
652
653TemplateTemplateParmDecl *
654TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
655 unsigned NumExpansions) {
656 auto *TTP =
657 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
658 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
659 nullptr, None);
660 TTP->NumExpandedParams = NumExpansions;
661 return TTP;
662}
663
664SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
665 return hasDefaultArgument() ? getDefaultArgument().getLocation()
666 : SourceLocation();
667}
668
669void TemplateTemplateParmDecl::setDefaultArgument(
670 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
671 if (DefArg.getArgument().isNull())
672 DefaultArgument.set(nullptr);
673 else
674 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
675}
676
677//===----------------------------------------------------------------------===//
678// TemplateArgumentList Implementation
679//===----------------------------------------------------------------------===//
680TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
681 : Arguments(getTrailingObjects<TemplateArgument>()),
682 NumArguments(Args.size()) {
683 std::uninitialized_copy(Args.begin(), Args.end(),
684 getTrailingObjects<TemplateArgument>());
685}
686
687TemplateArgumentList *
688TemplateArgumentList::CreateCopy(ASTContext &Context,
689 ArrayRef<TemplateArgument> Args) {
690 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
691 return new (Mem) TemplateArgumentList(Args);
692}
693
694FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
695 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
696 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
697 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
698 MemberSpecializationInfo *MSInfo) {
699 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
700 if (TemplateArgsAsWritten)
701 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
702 *TemplateArgsAsWritten);
703
704 void *Mem =
705 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
706 return new (Mem) FunctionTemplateSpecializationInfo(
707 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
708}
709
710//===----------------------------------------------------------------------===//
711// TemplateDecl Implementation
712//===----------------------------------------------------------------------===//
713
714void TemplateDecl::anchor() {}
715
716//===----------------------------------------------------------------------===//
717// ClassTemplateSpecializationDecl Implementation
718//===----------------------------------------------------------------------===//
719
720ClassTemplateSpecializationDecl::
721ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
722 DeclContext *DC, SourceLocation StartLoc,
723 SourceLocation IdLoc,
724 ClassTemplateDecl *SpecializedTemplate,
725 ArrayRef<TemplateArgument> Args,
726 ClassTemplateSpecializationDecl *PrevDecl)
727 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
728 SpecializedTemplate->getIdentifier(), PrevDecl),
729 SpecializedTemplate(SpecializedTemplate),
730 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
731 SpecializationKind(TSK_Undeclared) {
732}
733
734ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
735 Kind DK)
736 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
737 SourceLocation(), nullptr, nullptr),
738 SpecializationKind(TSK_Undeclared) {}
739
740ClassTemplateSpecializationDecl *
741ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
742 DeclContext *DC,
743 SourceLocation StartLoc,
744 SourceLocation IdLoc,
745 ClassTemplateDecl *SpecializedTemplate,
746 ArrayRef<TemplateArgument> Args,
747 ClassTemplateSpecializationDecl *PrevDecl) {
748 auto *Result =
749 new (Context, DC) ClassTemplateSpecializationDecl(
750 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
751 SpecializedTemplate, Args, PrevDecl);
752 Result->setMayHaveOutOfDateDef(false);
753
754 Context.getTypeDeclType(Result, PrevDecl);
755 return Result;
756}
757
758ClassTemplateSpecializationDecl *
759ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
760 unsigned ID) {
761 auto *Result =
762 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
763 Result->setMayHaveOutOfDateDef(false);
764 return Result;
765}
766
767void ClassTemplateSpecializationDecl::getNameForDiagnostic(
768 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
769 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
770
771 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
772 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
773 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
774 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
775 } else {
776 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
777 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
778 }
779}
780
781ClassTemplateDecl *
782ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
783 if (const auto *PartialSpec =
784 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
785 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
786 return SpecializedTemplate.get<ClassTemplateDecl*>();
787}
788
789SourceRange
790ClassTemplateSpecializationDecl::getSourceRange() const {
791 if (ExplicitInfo) {
792 SourceLocation Begin = getTemplateKeywordLoc();
793 if (Begin.isValid()) {
794 // Here we have an explicit (partial) specialization or instantiation.
795 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||((getSpecializationKind() == TSK_ExplicitSpecialization || getSpecializationKind
() == TSK_ExplicitInstantiationDeclaration || getSpecializationKind
() == TSK_ExplicitInstantiationDefinition) ? static_cast<void
> (0) : __assert_fail ("getSpecializationKind() == TSK_ExplicitSpecialization || getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || getSpecializationKind() == TSK_ExplicitInstantiationDefinition"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 797, __PRETTY_FUNCTION__))
796 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||((getSpecializationKind() == TSK_ExplicitSpecialization || getSpecializationKind
() == TSK_ExplicitInstantiationDeclaration || getSpecializationKind
() == TSK_ExplicitInstantiationDefinition) ? static_cast<void
> (0) : __assert_fail ("getSpecializationKind() == TSK_ExplicitSpecialization || getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || getSpecializationKind() == TSK_ExplicitInstantiationDefinition"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 797, __PRETTY_FUNCTION__))
797 getSpecializationKind() == TSK_ExplicitInstantiationDefinition)((getSpecializationKind() == TSK_ExplicitSpecialization || getSpecializationKind
() == TSK_ExplicitInstantiationDeclaration || getSpecializationKind
() == TSK_ExplicitInstantiationDefinition) ? static_cast<void
> (0) : __assert_fail ("getSpecializationKind() == TSK_ExplicitSpecialization || getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || getSpecializationKind() == TSK_ExplicitInstantiationDefinition"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 797, __PRETTY_FUNCTION__))
;
798 if (getExternLoc().isValid())
799 Begin = getExternLoc();
800 SourceLocation End = getBraceRange().getEnd();
801 if (End.isInvalid())
802 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
803 return SourceRange(Begin, End);
804 }
805 // An implicit instantiation of a class template partial specialization
806 // uses ExplicitInfo to record the TypeAsWritten, but the source
807 // locations should be retrieved from the instantiation pattern.
808 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
809 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
810 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
811 assert(inst_from != nullptr)((inst_from != nullptr) ? static_cast<void> (0) : __assert_fail
("inst_from != nullptr", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 811, __PRETTY_FUNCTION__))
;
812 return inst_from->getSourceRange();
813 }
814 else {
815 // No explicit info available.
816 llvm::PointerUnion<ClassTemplateDecl *,
817 ClassTemplatePartialSpecializationDecl *>
818 inst_from = getInstantiatedFrom();
819 if (inst_from.isNull())
820 return getSpecializedTemplate()->getSourceRange();
821 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
822 return ctd->getSourceRange();
823 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
824 ->getSourceRange();
825 }
826}
827
828//===----------------------------------------------------------------------===//
829// ConceptDecl Implementation
830//===----------------------------------------------------------------------===//
831ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
832 SourceLocation L, DeclarationName Name,
833 TemplateParameterList *Params,
834 Expr *ConstraintExpr) {
835 AdoptTemplateParameterList(Params, DC);
836 return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
837}
838
839ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
840 unsigned ID) {
841 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
842 DeclarationName(),
843 nullptr, nullptr);
844
845 return Result;
846}
847
848//===----------------------------------------------------------------------===//
849// ClassTemplatePartialSpecializationDecl Implementation
850//===----------------------------------------------------------------------===//
851void ClassTemplatePartialSpecializationDecl::anchor() {}
852
853ClassTemplatePartialSpecializationDecl::
854ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
855 DeclContext *DC,
856 SourceLocation StartLoc,
857 SourceLocation IdLoc,
858 TemplateParameterList *Params,
859 ClassTemplateDecl *SpecializedTemplate,
860 ArrayRef<TemplateArgument> Args,
861 const ASTTemplateArgumentListInfo *ArgInfos,
862 ClassTemplatePartialSpecializationDecl *PrevDecl)
863 : ClassTemplateSpecializationDecl(Context,
864 ClassTemplatePartialSpecialization,
865 TK, DC, StartLoc, IdLoc,
866 SpecializedTemplate, Args, PrevDecl),
867 TemplateParams(Params), ArgsAsWritten(ArgInfos),
868 InstantiatedFromMember(nullptr, false) {
869 AdoptTemplateParameterList(Params, this);
870}
871
872ClassTemplatePartialSpecializationDecl *
873ClassTemplatePartialSpecializationDecl::
874Create(ASTContext &Context, TagKind TK,DeclContext *DC,
875 SourceLocation StartLoc, SourceLocation IdLoc,
876 TemplateParameterList *Params,
877 ClassTemplateDecl *SpecializedTemplate,
878 ArrayRef<TemplateArgument> Args,
879 const TemplateArgumentListInfo &ArgInfos,
880 QualType CanonInjectedType,
881 ClassTemplatePartialSpecializationDecl *PrevDecl) {
882 const ASTTemplateArgumentListInfo *ASTArgInfos =
883 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
884
885 auto *Result = new (Context, DC)
886 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
887 Params, SpecializedTemplate, Args,
888 ASTArgInfos, PrevDecl);
889 Result->setSpecializationKind(TSK_ExplicitSpecialization);
890 Result->setMayHaveOutOfDateDef(false);
891
892 Context.getInjectedClassNameType(Result, CanonInjectedType);
893 return Result;
894}
895
896ClassTemplatePartialSpecializationDecl *
897ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
898 unsigned ID) {
899 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
900 Result->setMayHaveOutOfDateDef(false);
901 return Result;
902}
903
904//===----------------------------------------------------------------------===//
905// FriendTemplateDecl Implementation
906//===----------------------------------------------------------------------===//
907
908void FriendTemplateDecl::anchor() {}
909
910FriendTemplateDecl *
911FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
912 SourceLocation L,
913 MutableArrayRef<TemplateParameterList *> Params,
914 FriendUnion Friend, SourceLocation FLoc) {
915 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
916}
917
918FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
919 unsigned ID) {
920 return new (C, ID) FriendTemplateDecl(EmptyShell());
921}
922
923//===----------------------------------------------------------------------===//
924// TypeAliasTemplateDecl Implementation
925//===----------------------------------------------------------------------===//
926
927TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
928 DeclContext *DC,
929 SourceLocation L,
930 DeclarationName Name,
931 TemplateParameterList *Params,
932 NamedDecl *Decl) {
933 AdoptTemplateParameterList(Params, DC);
934 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
935}
936
937TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
938 unsigned ID) {
939 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
940 DeclarationName(), nullptr, nullptr);
941}
942
943RedeclarableTemplateDecl::CommonBase *
944TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
945 auto *CommonPtr = new (C) Common;
946 C.addDestruction(CommonPtr);
947 return CommonPtr;
948}
949
950//===----------------------------------------------------------------------===//
951// ClassScopeFunctionSpecializationDecl Implementation
952//===----------------------------------------------------------------------===//
953
954void ClassScopeFunctionSpecializationDecl::anchor() {}
955
956ClassScopeFunctionSpecializationDecl *
957ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
958 unsigned ID) {
959 return new (C, ID) ClassScopeFunctionSpecializationDecl(
960 nullptr, SourceLocation(), nullptr, nullptr);
961}
962
963//===----------------------------------------------------------------------===//
964// VarTemplateDecl Implementation
965//===----------------------------------------------------------------------===//
966
967VarTemplateDecl *VarTemplateDecl::getDefinition() {
968 VarTemplateDecl *CurD = this;
969 while (CurD) {
970 if (CurD->isThisDeclarationADefinition())
971 return CurD;
972 CurD = CurD->getPreviousDecl();
973 }
974 return nullptr;
975}
976
977VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
978 SourceLocation L, DeclarationName Name,
979 TemplateParameterList *Params,
980 VarDecl *Decl) {
981 AdoptTemplateParameterList(Params, DC);
982 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
983}
984
985VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
986 unsigned ID) {
987 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
988 DeclarationName(), nullptr, nullptr);
989}
990
991void VarTemplateDecl::LoadLazySpecializations() const {
992 loadLazySpecializationsImpl();
993}
994
995llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
996VarTemplateDecl::getSpecializations() const {
997 LoadLazySpecializations();
998 return getCommonPtr()->Specializations;
999}
1000
1001llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1002VarTemplateDecl::getPartialSpecializations() {
1003 LoadLazySpecializations();
1004 return getCommonPtr()->PartialSpecializations;
1005}
1006
1007RedeclarableTemplateDecl::CommonBase *
1008VarTemplateDecl::newCommon(ASTContext &C) const {
1009 auto *CommonPtr = new (C) Common;
1010 C.addDestruction(CommonPtr);
1011 return CommonPtr;
1012}
1013
1014VarTemplateSpecializationDecl *
1015VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1016 void *&InsertPos) {
1017 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
1018}
1019
1020void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1021 void *InsertPos) {
1022 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1023}
1024
1025VarTemplatePartialSpecializationDecl *
1026VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1027 void *&InsertPos) {
1028 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1029}
1030
1031void VarTemplateDecl::AddPartialSpecialization(
1032 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1033 if (InsertPos)
1034 getPartialSpecializations().InsertNode(D, InsertPos);
1035 else {
1036 VarTemplatePartialSpecializationDecl *Existing =
1037 getPartialSpecializations().GetOrInsertNode(D);
1038 (void)Existing;
1039 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?")((Existing->isCanonicalDecl() && "Non-canonical specialization?"
) ? static_cast<void> (0) : __assert_fail ("Existing->isCanonicalDecl() && \"Non-canonical specialization?\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 1039, __PRETTY_FUNCTION__))
;
1040 }
1041
1042 if (ASTMutationListener *L = getASTMutationListener())
1043 L->AddedCXXTemplateSpecialization(this, D);
1044}
1045
1046void VarTemplateDecl::getPartialSpecializations(
1047 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1048 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1049 getPartialSpecializations();
1050 PS.clear();
1051 PS.reserve(PartialSpecs.size());
1052 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1053 PS.push_back(P.getMostRecentDecl());
1054}
1055
1056VarTemplatePartialSpecializationDecl *
1057VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1058 VarTemplatePartialSpecializationDecl *D) {
1059 Decl *DCanon = D->getCanonicalDecl();
1060 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1061 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1062 return P.getMostRecentDecl();
1063 }
1064
1065 return nullptr;
1066}
1067
1068//===----------------------------------------------------------------------===//
1069// VarTemplateSpecializationDecl Implementation
1070//===----------------------------------------------------------------------===//
1071
1072VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1073 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1074 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1075 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1076 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1077 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1078 SpecializedTemplate(SpecializedTemplate),
1079 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1080 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1081
1082VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1083 ASTContext &C)
1084 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1085 QualType(), nullptr, SC_None),
1086 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1087
1088VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1089 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1090 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1091 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1092 return new (Context, DC) VarTemplateSpecializationDecl(
1093 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1094 SpecializedTemplate, T, TInfo, S, Args);
1095}
1096
1097VarTemplateSpecializationDecl *
1098VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1099 return new (C, ID)
1100 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1101}
1102
1103void VarTemplateSpecializationDecl::getNameForDiagnostic(
1104 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1105 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1106
1107 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1108 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1109 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1110 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
1111 } else {
1112 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1113 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
1114 }
1115}
1116
1117VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1118 if (const auto *PartialSpec =
1119 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1120 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1121 return SpecializedTemplate.get<VarTemplateDecl *>();
1122}
1123
1124void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1125 const TemplateArgumentListInfo &ArgsInfo) {
1126 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1127 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1128 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1129 TemplateArgsInfo.addArgument(Loc);
1130}
1131
1132//===----------------------------------------------------------------------===//
1133// VarTemplatePartialSpecializationDecl Implementation
1134//===----------------------------------------------------------------------===//
1135
1136void VarTemplatePartialSpecializationDecl::anchor() {}
1137
1138VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1139 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1140 SourceLocation IdLoc, TemplateParameterList *Params,
1141 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1142 StorageClass S, ArrayRef<TemplateArgument> Args,
1143 const ASTTemplateArgumentListInfo *ArgInfos)
1144 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1145 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1146 TInfo, S, Args),
1147 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1148 InstantiatedFromMember(nullptr, false) {
1149 // TODO: The template parameters should be in DC by now. Verify.
1150 // AdoptTemplateParameterList(Params, DC);
1151}
1152
1153VarTemplatePartialSpecializationDecl *
1154VarTemplatePartialSpecializationDecl::Create(
1155 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1156 SourceLocation IdLoc, TemplateParameterList *Params,
1157 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1158 StorageClass S, ArrayRef<TemplateArgument> Args,
1159 const TemplateArgumentListInfo &ArgInfos) {
1160 const ASTTemplateArgumentListInfo *ASTArgInfos
1161 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1162
1163 auto *Result =
1164 new (Context, DC) VarTemplatePartialSpecializationDecl(
1165 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1166 S, Args, ASTArgInfos);
1167 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1168 return Result;
1169}
1170
1171VarTemplatePartialSpecializationDecl *
1172VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1173 unsigned ID) {
1174 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1175}
1176
1177static TemplateParameterList *
1178createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1179 // typename T
1180 auto *T = TemplateTypeParmDecl::Create(
1181 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1182 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1183 T->setImplicit(true);
1184
1185 // T ...Ints
1186 TypeSourceInfo *TI =
1187 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1188 auto *N = NonTypeTemplateParmDecl::Create(
1189 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1190 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1191 N->setImplicit(true);
1192
1193 // <typename T, T ...Ints>
1194 NamedDecl *P[2] = {T, N};
1195 auto *TPL = TemplateParameterList::Create(
1196 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1197
1198 // template <typename T, ...Ints> class IntSeq
1199 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1200 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1201 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1202 TemplateTemplateParm->setImplicit(true);
1203
1204 // typename T
1205 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1206 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1207 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1208 TemplateTypeParm->setImplicit(true);
1209
1210 // T N
1211 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1212 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1213 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1214 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1215 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1216 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1217 NonTypeTemplateParm};
1218
1219 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1220 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1221 Params, SourceLocation(), nullptr);
1222}
1223
1224static TemplateParameterList *
1225createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1226 // std::size_t Index
1227 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1228 auto *Index = NonTypeTemplateParmDecl::Create(
1229 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1230 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1231
1232 // typename ...T
1233 auto *Ts = TemplateTypeParmDecl::Create(
1234 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1235 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1236 Ts->setImplicit(true);
1237
1238 // template <std::size_t Index, typename ...T>
1239 NamedDecl *Params[] = {Index, Ts};
1240 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1241 llvm::makeArrayRef(Params),
1242 SourceLocation(), nullptr);
1243}
1244
1245static TemplateParameterList *createBuiltinTemplateParameterList(
1246 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1247 switch (BTK) {
1248 case BTK__make_integer_seq:
1249 return createMakeIntegerSeqParameterList(C, DC);
1250 case BTK__type_pack_element:
1251 return createTypePackElementParameterList(C, DC);
1252 }
1253
1254 llvm_unreachable("unhandled BuiltinTemplateKind!")::llvm::llvm_unreachable_internal("unhandled BuiltinTemplateKind!"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/DeclTemplate.cpp"
, 1254)
;
1255}
1256
1257void BuiltinTemplateDecl::anchor() {}
1258
1259BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1260 DeclarationName Name,
1261 BuiltinTemplateKind BTK)
1262 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1263 createBuiltinTemplateParameterList(C, DC, BTK)),
1264 BTK(BTK) {}