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