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