]> git.proxmox.com Git - rustc.git/blame - src/llvm/tools/clang/include/clang/AST/TemplateBase.h
Imported Upstream version 0.6
[rustc.git] / src / llvm / tools / clang / include / clang / AST / TemplateBase.h
CommitLineData
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
25namespace llvm {
26 class FoldingSetNodeID;
27}
28
29namespace clang {
30
31class DiagnosticBuilder;
32class Expr;
33struct PrintingPolicy;
34class TypeSourceInfo;
35class ValueDecl;
36
37/// \brief Represents a template argument within a class template
38/// specialization.
39class TemplateArgument {
40public:
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
71private:
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
105public:
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.
336struct TemplateArgumentLocInfo {
337private:
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
351public:
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.
392class TemplateArgumentLoc {
393 TemplateArgument Argument;
394 TemplateArgumentLocInfo LocInfo;
395
396public:
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.
499class 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
508public:
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.
540struct 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>.
586struct 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
619const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
620 const TemplateArgument &Arg);
621
622inline TemplateSpecializationType::iterator
623 TemplateSpecializationType::end() const {
624 return getArgs() + getNumArgs();
625}
626
627inline DependentTemplateSpecializationType::iterator
628 DependentTemplateSpecializationType::end() const {
629 return getArgs() + getNumArgs();
630}
631
632inline const TemplateArgument &
633 TemplateSpecializationType::getArg(unsigned Idx) const {
634 assert(Idx < getNumArgs() && "Template argument out of range");
635 return getArgs()[Idx];
636}
637
638inline 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