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