]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / include / clang / AST / TemplateBase.h
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