1//===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===//
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 provides definitions which are common for all kinds of
10// template representation.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
15#define LLVM_CLANG_AST_TEMPLATEBASE_H
16
17#include "clang/AST/DependenceFlags.h"
18#include "clang/AST/NestedNameSpecifier.h"
19#include "clang/AST/TemplateName.h"
20#include "clang/AST/Type.h"
21#include "clang/Basic/LLVM.h"
22#include "clang/Basic/SourceLocation.h"
23#include "llvm/ADT/APInt.h"
24#include "llvm/ADT/APSInt.h"
25#include "llvm/ADT/ArrayRef.h"
26#include "llvm/ADT/None.h"
27#include "llvm/ADT/Optional.h"
28#include "llvm/ADT/SmallVector.h"
29#include "llvm/Support/Compiler.h"
30#include "llvm/Support/TrailingObjects.h"
31#include <cassert>
32#include <cstddef>
33#include <cstdint>
34
35namespace llvm {
36
37class FoldingSetNodeID;
38
39// Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a
40// full definition of Expr, but this file only sees a forward del because of
41// the dependency.
42template <> struct PointerLikeTypeTraits<clang::Expr *> {
43 static inline void *getAsVoidPointer(clang::Expr *P) { return P; }
44 static inline clang::Expr *getFromVoidPointer(void *P) {
45 return static_cast<clang::Expr *>(P);
46 }
47 static constexpr int NumLowBitsAvailable = 2;
48};
49
50} // namespace llvm
51
52namespace clang {
53
54class ASTContext;
55class DiagnosticBuilder;
56class Expr;
57struct PrintingPolicy;
58class TypeSourceInfo;
59class ValueDecl;
60
61/// Represents a template argument.
62class TemplateArgument {
63public:
64 /// The kind of template argument we're storing.
65 enum ArgKind {
66 /// Represents an empty template argument, e.g., one that has not
67 /// been deduced.
68 Null = 0,
69
70 /// The template argument is a type.
71 Type,
72
73 /// The template argument is a declaration that was provided for a pointer,
74 /// reference, or pointer to member non-type template parameter.
75 Declaration,
76
77 /// The template argument is a null pointer or null pointer to member that
78 /// was provided for a non-type template parameter.
79 NullPtr,
80
81 /// The template argument is an integral value stored in an llvm::APSInt
82 /// that was provided for an integral non-type template parameter.
83 Integral,
84
85 /// The template argument is a template name that was provided for a
86 /// template template parameter.
87 Template,
88
89 /// The template argument is a pack expansion of a template name that was
90 /// provided for a template template parameter.
91 TemplateExpansion,
92
93 /// The template argument is an expression, and we've not resolved it to one
94 /// of the other forms yet, either because it's dependent or because we're
95 /// representing a non-canonical template argument (for instance, in a
96 /// TemplateSpecializationType).
97 Expression,
98
99 /// The template argument is actually a parameter pack. Arguments are stored
100 /// in the Args struct.
101 Pack
102 };
103
104private:
105 /// The kind of template argument we're storing.
106
107 struct DA {
108 unsigned Kind;
109 void *QT;
110 ValueDecl *D;
111 };
112 struct I {
113 unsigned Kind;
114 // We store a decomposed APSInt with the data allocated by ASTContext if
115 // BitWidth > 64. The memory may be shared between multiple
116 // TemplateArgument instances.
117 unsigned BitWidth : 31;
118 unsigned IsUnsigned : 1;
119 union {
120 /// Used to store the <= 64 bits integer value.
121 uint64_t VAL;
122
123 /// Used to store the >64 bits integer value.
124 const uint64_t *pVal;
125 };
126 void *Type;
127 };
128 struct A {
129 unsigned Kind;
130 unsigned NumArgs;
131 const TemplateArgument *Args;
132 };
133 struct TA {
134 unsigned Kind;
135 unsigned NumExpansions;
136 void *Name;
137 };
138 struct TV {
139 unsigned Kind;
140 uintptr_t V;
141 };
142 union {
143 struct DA DeclArg;
144 struct I Integer;
145 struct A Args;
146 struct TA TemplateArg;
147 struct TV TypeOrValue;
148 };
149
150public:
151 /// Construct an empty, invalid template argument.
152 constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
153
154 /// Construct a template type argument.
155 TemplateArgument(QualType T, bool isNullPtr = false) {
156 TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
157 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
158 }
159
160 /// Construct a template argument that refers to a
161 /// declaration, which is either an external declaration or a
162 /// template declaration.
163 TemplateArgument(ValueDecl *D, QualType QT) {
164 assert(D && "Expected decl");
165 DeclArg.Kind = Declaration;
166 DeclArg.QT = QT.getAsOpaquePtr();
167 DeclArg.D = D;
168 }
169
170 /// Construct an integral constant template argument. The memory to
171 /// store the value is allocated with Ctx.
172 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
173
174 /// Construct an integral constant template argument with the same
175 /// value as Other but a different type.
176 TemplateArgument(const TemplateArgument &Other, QualType Type) {
177 Integer = Other.Integer;
178 Integer.Type = Type.getAsOpaquePtr();
179 }
180
181 /// Construct a template argument that is a template.
182 ///
183 /// This form of template argument is generally used for template template
184 /// parameters. However, the template name could be a dependent template
185 /// name that ends up being instantiated to a function template whose address
186 /// is taken.
187 ///
188 /// \param Name The template name.
189 TemplateArgument(TemplateName Name) {
190 TemplateArg.Kind = Template;
191 TemplateArg.Name = Name.getAsVoidPointer();
192 TemplateArg.NumExpansions = 0;
193 }
194
195 /// Construct a template argument that is a template pack expansion.
196 ///
197 /// This form of template argument is generally used for template template
198 /// parameters. However, the template name could be a dependent template
199 /// name that ends up being instantiated to a function template whose address
200 /// is taken.
201 ///
202 /// \param Name The template name.
203 ///
204 /// \param NumExpansions The number of expansions that will be generated by
205 /// instantiating
206 TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
207 TemplateArg.Kind = TemplateExpansion;
208 TemplateArg.Name = Name.getAsVoidPointer();
209 if (NumExpansions)
210 TemplateArg.NumExpansions = *NumExpansions + 1;
211 else
212 TemplateArg.NumExpansions = 0;
213 }
214
215 /// Construct a template argument that is an expression.
216 ///
217 /// This form of template argument only occurs in template argument
218 /// lists used for dependent types and for expression; it will not
219 /// occur in a non-dependent, canonical template argument list.
220 TemplateArgument(Expr *E) {
221 TypeOrValue.Kind = Expression;
222 TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
223 }
224
225 /// Construct a template argument that is a template argument pack.
226 ///
227 /// We assume that storage for the template arguments provided
228 /// outlives the TemplateArgument itself.
229 explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
230 this->Args.Kind = Pack;
231 this->Args.Args = Args.data();
232 this->Args.NumArgs = Args.size();
233 }
234
235 TemplateArgument(TemplateName, bool) = delete;
236
237 static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
238
239 /// Create a new template argument pack by copying the given set of
240 /// template arguments.
241 static TemplateArgument CreatePackCopy(ASTContext &Context,
242 ArrayRef<TemplateArgument> Args);
243
244 /// Return the kind of stored template argument.
245 ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
246
247 /// Determine whether this template argument has no value.
248 bool isNull() const { return getKind() == Null; }
249
250 TemplateArgumentDependence getDependence() const;
251
252 /// Whether this template argument is dependent on a template
253 /// parameter such that its result can change from one instantiation to
254 /// another.
255 bool isDependent() const;
256
257 /// Whether this template argument is dependent on a template
258 /// parameter.
259 bool isInstantiationDependent() const;
260
261 /// Whether this template argument contains an unexpanded
262 /// parameter pack.
263 bool containsUnexpandedParameterPack() const;
264
265 /// Determine whether this template argument is a pack expansion.
266 bool isPackExpansion() const;
267
268 /// Retrieve the type for a type template argument.
269 QualType getAsType() const {
270 assert(getKind() == Type && "Unexpected kind");
271 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
272 }
273
274 /// Retrieve the declaration for a declaration non-type
275 /// template argument.
276 ValueDecl *getAsDecl() const {
277 assert(getKind() == Declaration && "Unexpected kind");
278 return DeclArg.D;
279 }
280
281 QualType getParamTypeForDecl() const {
282 assert(getKind() == Declaration && "Unexpected kind");
283 return QualType::getFromOpaquePtr(DeclArg.QT);
284 }
285
286 /// Retrieve the type for null non-type template argument.
287 QualType getNullPtrType() const {
288 assert(getKind() == NullPtr && "Unexpected kind");
289 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
290 }
291
292 /// Retrieve the template name for a template name argument.
293 TemplateName getAsTemplate() const {
294 assert(getKind() == Template && "Unexpected kind");
295 return TemplateName::getFromVoidPointer(TemplateArg.Name);
296 }
297
298 /// Retrieve the template argument as a template name; if the argument
299 /// is a pack expansion, return the pattern as a template name.
300 TemplateName getAsTemplateOrTemplatePattern() const {
301 assert((getKind() == Template || getKind() == TemplateExpansion) &&
302 "Unexpected kind");
303
304 return TemplateName::getFromVoidPointer(TemplateArg.Name);
305 }
306
307 /// Retrieve the number of expansions that a template template argument
308 /// expansion will produce, if known.
309 Optional<unsigned> getNumTemplateExpansions() const;
310
311 /// Retrieve the template argument as an integral value.
312 // FIXME: Provide a way to read the integral data without copying the value.
313 llvm::APSInt getAsIntegral() const {
314 assert(getKind() == Integral && "Unexpected kind");
315
316 using namespace llvm;
317
318 if (Integer.BitWidth <= 64)
319 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
320
321 unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
322 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
323 Integer.IsUnsigned);
324 }
325
326 /// Retrieve the type of the integral value.
327 QualType getIntegralType() const {
328 assert(getKind() == Integral && "Unexpected kind");
329 return QualType::getFromOpaquePtr(Integer.Type);
330 }
331
332 void setIntegralType(QualType T) {
333 assert(getKind() == Integral && "Unexpected kind");
334 Integer.Type = T.getAsOpaquePtr();
335 }
336
337 /// If this is a non-type template argument, get its type. Otherwise,
338 /// returns a null QualType.
339 QualType getNonTypeTemplateArgumentType() const;
340
341 /// Retrieve the template argument as an expression.
342 Expr *getAsExpr() const {
343 assert(getKind() == Expression && "Unexpected kind");
344 return reinterpret_cast<Expr *>(TypeOrValue.V);
345 }
346
347 /// Iterator that traverses the elements of a template argument pack.
348 using pack_iterator = const TemplateArgument *;
349
350 /// Iterator referencing the first argument of a template argument
351 /// pack.
352 pack_iterator pack_begin() const {
353 assert(getKind() == Pack);
354 return Args.Args;
355 }
356
357 /// Iterator referencing one past the last argument of a template
358 /// argument pack.
359 pack_iterator pack_end() const {
360 assert(getKind() == Pack);
361 return Args.Args + Args.NumArgs;
362 }
363
364 /// Iterator range referencing all of the elements of a template
365 /// argument pack.
366 ArrayRef<TemplateArgument> pack_elements() const {
367 return llvm::makeArrayRef(pack_begin(), pack_end());
368 }
369
370 /// The number of template arguments in the given template argument
371 /// pack.
372 unsigned pack_size() const {
373 assert(getKind() == Pack);
374 return Args.NumArgs;
375 }
376
377 /// Return the array of arguments in this template argument pack.
378 ArrayRef<TemplateArgument> getPackAsArray() const {
379 assert(getKind() == Pack);
380 return llvm::makeArrayRef(Args.Args, Args.NumArgs);
381 }
382
383 /// Determines whether two template arguments are superficially the
384 /// same.
385 bool structurallyEquals(const TemplateArgument &Other) const;
386
387 /// When the template argument is a pack expansion, returns
388 /// the pattern of the pack expansion.
389 TemplateArgument getPackExpansionPattern() const;
390
391 /// Print this template argument to the given output stream.
392 void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
393
394 /// Debugging aid that dumps the template argument.
395 void dump(raw_ostream &Out) const;
396
397 /// Debugging aid that dumps the template argument to standard error.
398 void dump() const;
399
400 /// Used to insert TemplateArguments into FoldingSets.
401 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
402};
403
404/// Location information for a TemplateArgument.
405struct TemplateArgumentLocInfo {
406private:
407 struct TemplateTemplateArgLocInfo {
408 // FIXME: We'd like to just use the qualifier in the TemplateName,
409 // but template arguments get canonicalized too quickly.
410 NestedNameSpecifier *Qualifier;
411 void *QualifierLocData;
412 SourceLocation TemplateNameLoc;
413 SourceLocation EllipsisLoc;
414 };
415
416 llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
417 Pointer;
418
419 TemplateTemplateArgLocInfo *getTemplate() const {
420 return Pointer.get<TemplateTemplateArgLocInfo *>();
421 }
422
423public:
424 TemplateArgumentLocInfo() {}
425 TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
426
427 TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
428 // Ctx is used for allocation -- this case is unusually large and also rare,
429 // so we store the payload out-of-line.
430 TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
431 SourceLocation TemplateNameLoc,
432 SourceLocation EllipsisLoc);
433
434 TypeSourceInfo *getAsTypeSourceInfo() const {
435 return Pointer.get<TypeSourceInfo *>();
436 }
437
438 Expr *getAsExpr() const { return Pointer.get<Expr *>(); }
439
440 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
441 const auto *Template = getTemplate();
442 return NestedNameSpecifierLoc(Template->Qualifier,
443 Template->QualifierLocData);
444 }
445
446 SourceLocation getTemplateNameLoc() const {
447 return getTemplate()->TemplateNameLoc;
448 }
449
450 SourceLocation getTemplateEllipsisLoc() const {
451 return getTemplate()->EllipsisLoc;
452 }
453};
454
455/// Location wrapper for a TemplateArgument. TemplateArgument is to
456/// TemplateArgumentLoc as Type is to TypeLoc.
457class TemplateArgumentLoc {
458 TemplateArgument Argument;
459 TemplateArgumentLocInfo LocInfo;
460
461public:
462 TemplateArgumentLoc() {}
463
464 TemplateArgumentLoc(const TemplateArgument &Argument,
465 TemplateArgumentLocInfo Opaque)
466 : Argument(Argument), LocInfo(Opaque) {}
467
468 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
469 : Argument(Argument), LocInfo(TInfo) {
470 assert(Argument.getKind() == TemplateArgument::Type);
471 }
472
473 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
474 : Argument(Argument), LocInfo(E) {
475
476 // Permit any kind of template argument that can be represented with an
477 // expression.
478 assert(Argument.getKind() == TemplateArgument::NullPtr ||
479 Argument.getKind() == TemplateArgument::Integral ||
480 Argument.getKind() == TemplateArgument::Declaration ||
481 Argument.getKind() == TemplateArgument::Expression);
482 }
483
484 TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
485 NestedNameSpecifierLoc QualifierLoc,
486 SourceLocation TemplateNameLoc,
487 SourceLocation EllipsisLoc = SourceLocation())
488 : Argument(Argument),
489 LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
490 assert(Argument.getKind() == TemplateArgument::Template ||
491 Argument.getKind() == TemplateArgument::TemplateExpansion);
492 }
493
494 /// - Fetches the primary location of the argument.
495 SourceLocation getLocation() const {
496 if (Argument.getKind() == TemplateArgument::Template ||
497 Argument.getKind() == TemplateArgument::TemplateExpansion)
498 return getTemplateNameLoc();
499
500 return getSourceRange().getBegin();
501 }
502
503 /// - Fetches the full source range of the argument.
504 SourceRange getSourceRange() const LLVM_READONLY;
505
506 const TemplateArgument &getArgument() const {
507 return Argument;
508 }
509
510 TemplateArgumentLocInfo getLocInfo() const {
511 return LocInfo;
512 }
513
514 TypeSourceInfo *getTypeSourceInfo() const {
515 if (Argument.getKind() != TemplateArgument::Type)
516 return nullptr;
517 return LocInfo.getAsTypeSourceInfo();
518 }
519
520 Expr *getSourceExpression() const {
521 assert(Argument.getKind() == TemplateArgument::Expression);
522 return LocInfo.getAsExpr();
523 }
524
525 Expr *getSourceDeclExpression() const {
526 assert(Argument.getKind() == TemplateArgument::Declaration);
527 return LocInfo.getAsExpr();
528 }
529
530 Expr *getSourceNullPtrExpression() const {
531 assert(Argument.getKind() == TemplateArgument::NullPtr);
532 return LocInfo.getAsExpr();
533 }
534
535 Expr *getSourceIntegralExpression() const {
536 assert(Argument.getKind() == TemplateArgument::Integral);
537 return LocInfo.getAsExpr();
538 }
539
540 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
541 if (Argument.getKind() != TemplateArgument::Template &&
542 Argument.getKind() != TemplateArgument::TemplateExpansion)
543 return NestedNameSpecifierLoc();
544 return LocInfo.getTemplateQualifierLoc();
545 }
546
547 SourceLocation getTemplateNameLoc() const {
548 if (Argument.getKind() != TemplateArgument::Template &&
549 Argument.getKind() != TemplateArgument::TemplateExpansion)
550 return SourceLocation();
551 return LocInfo.getTemplateNameLoc();
552 }
553
554 SourceLocation getTemplateEllipsisLoc() const {
555 if (Argument.getKind() != TemplateArgument::TemplateExpansion)
556 return SourceLocation();
557 return LocInfo.getTemplateEllipsisLoc();
558 }
559};
560
561/// A convenient class for passing around template argument
562/// information. Designed to be passed by reference.
563class TemplateArgumentListInfo {
564 SmallVector<TemplateArgumentLoc, 8> Arguments;
565 SourceLocation LAngleLoc;
566 SourceLocation RAngleLoc;
567
568public:
569 TemplateArgumentListInfo() = default;
570
571 TemplateArgumentListInfo(SourceLocation LAngleLoc,
572 SourceLocation RAngleLoc)
573 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
574
575 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
576 // instead.
577 void *operator new(size_t bytes, ASTContext &C) = delete;
578
579 SourceLocation getLAngleLoc() const { return LAngleLoc; }
580 SourceLocation getRAngleLoc() const { return RAngleLoc; }
581
582 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
583 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
584
585 unsigned size() const { return Arguments.size(); }
586
587 const TemplateArgumentLoc *getArgumentArray() const {
588 return Arguments.data();
589 }
590
591 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
592 return Arguments;
593 }
594
595 const TemplateArgumentLoc &operator[](unsigned I) const {
596 return Arguments[I];
597 }
598
599 TemplateArgumentLoc &operator[](unsigned I) {
600 return Arguments[I];
601 }
602
603 void addArgument(const TemplateArgumentLoc &Loc) {
604 Arguments.push_back(Loc);
605 }
606};
607
608/// Represents an explicit template argument list in C++, e.g.,
609/// the "<int>" in "sort<int>".
610/// This is safe to be used inside an AST node, in contrast with
611/// TemplateArgumentListInfo.
612struct ASTTemplateArgumentListInfo final
613 : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
614 TemplateArgumentLoc> {
615private:
616 friend class ASTNodeImporter;
617 friend TrailingObjects;
618
619 ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
620
621public:
622 /// The source location of the left angle bracket ('<').
623 SourceLocation LAngleLoc;
624
625 /// The source location of the right angle bracket ('>').
626 SourceLocation RAngleLoc;
627
628 /// The number of template arguments in TemplateArgs.
629 unsigned NumTemplateArgs;
630
631 SourceLocation getLAngleLoc() const { return LAngleLoc; }
632 SourceLocation getRAngleLoc() const { return RAngleLoc; }
633
634 /// Retrieve the template arguments
635 const TemplateArgumentLoc *getTemplateArgs() const {
636 return getTrailingObjects<TemplateArgumentLoc>();
637 }
638 unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
639
640 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
641 return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
642 }
643
644 const TemplateArgumentLoc &operator[](unsigned I) const {
645 return getTemplateArgs()[I];
646 }
647
648 static const ASTTemplateArgumentListInfo *
649 Create(const ASTContext &C, const TemplateArgumentListInfo &List);
650};
651
652/// Represents an explicit template argument list in C++, e.g.,
653/// the "<int>" in "sort<int>".
654///
655/// It is intended to be used as a trailing object on AST nodes, and
656/// as such, doesn't contain the array of TemplateArgumentLoc itself,
657/// but expects the containing object to also provide storage for
658/// that.
659struct alignas(void *) ASTTemplateKWAndArgsInfo {
660 /// The source location of the left angle bracket ('<').
661 SourceLocation LAngleLoc;
662
663 /// The source location of the right angle bracket ('>').
664 SourceLocation RAngleLoc;
665
666 /// The source location of the template keyword; this is used
667 /// as part of the representation of qualified identifiers, such as
668 /// S<T>::template apply<T>. Will be empty if this expression does
669 /// not have a template keyword.
670 SourceLocation TemplateKWLoc;
671
672 /// The number of template arguments in TemplateArgs.
673 unsigned NumTemplateArgs;
674
675 void initializeFrom(SourceLocation TemplateKWLoc,
676 const TemplateArgumentListInfo &List,
677 TemplateArgumentLoc *OutArgArray);
678 // FIXME: The parameter Deps is the result populated by this method, the
679 // caller doesn't need it since it is populated by computeDependence. remove
680 // it.
681 void initializeFrom(SourceLocation TemplateKWLoc,
682 const TemplateArgumentListInfo &List,
683 TemplateArgumentLoc *OutArgArray,
684 TemplateArgumentDependence &Deps);
685 void initializeFrom(SourceLocation TemplateKWLoc);
686
687 void copyInto(const TemplateArgumentLoc *ArgArray,
688 TemplateArgumentListInfo &List) const;
689};
690
691const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
692 const TemplateArgument &Arg);
693
694inline TemplateSpecializationType::iterator
695 TemplateSpecializationType::end() const {
696 return getArgs() + getNumArgs();
697}
698
699inline DependentTemplateSpecializationType::iterator
700 DependentTemplateSpecializationType::end() const {
701 return getArgs() + getNumArgs();
702}
703
704inline const TemplateArgument &
705 TemplateSpecializationType::getArg(unsigned Idx) const {
706 assert(Idx < getNumArgs() && "Template argument out of range");
707 return getArgs()[Idx];
708}
709
710inline const TemplateArgument &
711 DependentTemplateSpecializationType::getArg(unsigned Idx) const {
712 assert(Idx < getNumArgs() && "Template argument out of range");
713 return getArgs()[Idx];
714}
715
716inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
717 assert(Idx < getNumArgs() && "Template argument out of range");
718 return getArgs()[Idx];
719}
720
721} // namespace clang
722
723#endif // LLVM_CLANG_AST_TEMPLATEBASE_H
724