]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[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 "llvm/ADT/APSInt.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "clang/AST/Type.h"
22 #include "clang/AST/TemplateName.h"
23
24 namespace llvm {
25   class FoldingSetNodeID;
26   class raw_ostream;
27 }
28
29 namespace clang {
30
31 class Decl;
32 class DiagnosticBuilder;
33 class Expr;
34 struct PrintingPolicy;
35 class TypeSourceInfo;
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. Its value is stored in the
47     /// TypeOrValue field.
48     Type,
49     /// The template argument is a declaration that was provided for a pointer
50     /// or reference non-type template parameter.
51     Declaration,
52     /// The template argument is an integral value stored in an llvm::APSInt
53     /// that was provided for an integral non-type template parameter. 
54     Integral,
55     /// The template argument is a template name that was provided for a 
56     /// template template parameter.
57     Template,
58     /// The template argument is a pack expansion of a template name that was 
59     /// provided for a template template parameter.
60     TemplateExpansion,
61     /// The template argument is a value- or type-dependent expression
62     /// stored in an Expr*.
63     Expression,
64     /// The template argument is actually a parameter pack. Arguments are stored
65     /// in the Args struct.
66     Pack
67   };
68
69 private:
70   /// \brief The kind of template argument we're storing.
71   unsigned Kind;
72
73   union {
74     uintptr_t TypeOrValue;
75     struct {
76       char Value[sizeof(llvm::APSInt)];
77       void *Type;
78     } Integer;
79     struct {
80       const TemplateArgument *Args;
81       unsigned NumArgs;
82     } Args;
83     struct {
84       void *Name;
85       unsigned NumExpansions;
86     } TemplateArg;
87   };
88
89   TemplateArgument(TemplateName, bool); // DO NOT USE
90   
91 public:
92   /// \brief Construct an empty, invalid template argument.
93   TemplateArgument() : Kind(Null), TypeOrValue(0) { }
94
95   /// \brief Construct a template type argument.
96   TemplateArgument(QualType T) : Kind(Type) {
97     TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
98   }
99
100   /// \brief Construct a template argument that refers to a
101   /// declaration, which is either an external declaration or a
102   /// template declaration.
103   TemplateArgument(Decl *D) : Kind(Declaration) {
104     // FIXME: Need to be sure we have the "canonical" declaration!
105     TypeOrValue = reinterpret_cast<uintptr_t>(D);
106   }
107
108   /// \brief Construct an integral constant template argument.
109   TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) {
110     // FIXME: Large integral values will get leaked. Do something
111     // similar to what we did with IntegerLiteral.
112     new (Integer.Value) llvm::APSInt(Value);
113     Integer.Type = Type.getAsOpaquePtr();
114   }
115
116   /// \brief Construct a template argument that is a template.
117   ///
118   /// This form of template argument is generally used for template template
119   /// parameters. However, the template name could be a dependent template
120   /// name that ends up being instantiated to a function template whose address
121   /// is taken.
122   ///
123   /// \param Name The template name.
124   TemplateArgument(TemplateName Name) : Kind(Template) 
125   {
126     TemplateArg.Name = Name.getAsVoidPointer();
127     TemplateArg.NumExpansions = 0;
128   }
129
130   /// \brief Construct a template argument that is a template pack expansion.
131   ///
132   /// This form of template argument is generally used for template template
133   /// parameters. However, the template name could be a dependent template
134   /// name that ends up being instantiated to a function template whose address
135   /// is taken.
136   ///
137   /// \param Name The template name.
138   ///
139   /// \param NumExpansions The number of expansions that will be generated by
140   /// instantiating
141   TemplateArgument(TemplateName Name, llvm::Optional<unsigned> NumExpansions)
142     : Kind(TemplateExpansion) 
143   {
144     TemplateArg.Name = Name.getAsVoidPointer();
145     if (NumExpansions)
146       TemplateArg.NumExpansions = *NumExpansions + 1;
147     else
148       TemplateArg.NumExpansions = 0;
149   }
150
151   /// \brief Construct a template argument that is an expression.
152   ///
153   /// This form of template argument only occurs in template argument
154   /// lists used for dependent types and for expression; it will not
155   /// occur in a non-dependent, canonical template argument list.
156   TemplateArgument(Expr *E) : Kind(Expression) {
157     TypeOrValue = reinterpret_cast<uintptr_t>(E);
158   }
159
160   /// \brief Construct a template argument that is a template argument pack.
161   ///
162   /// We assume that storage for the template arguments provided
163   /// outlives the TemplateArgument itself.
164   TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){
165     this->Args.Args = Args;
166     this->Args.NumArgs = NumArgs;
167   }
168
169   /// \brief Copy constructor for a template argument.
170   TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
171     // FIXME: Large integral values will get leaked. Do something
172     // similar to what we did with IntegerLiteral.
173     if (Kind == Integral) {
174       new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
175       Integer.Type = Other.Integer.Type;
176     } else if (Kind == Pack) {
177       Args.NumArgs = Other.Args.NumArgs;
178       Args.Args = Other.Args.Args;
179     } else if (Kind == Template || Kind == TemplateExpansion) {
180       TemplateArg.Name = Other.TemplateArg.Name;
181       TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions;
182     } else
183       TypeOrValue = Other.TypeOrValue;
184   }
185
186   TemplateArgument& operator=(const TemplateArgument& Other) {
187     using llvm::APSInt;
188
189     if (Kind == Other.Kind && Kind == Integral) {
190       // Copy integral values.
191       *this->getAsIntegral() = *Other.getAsIntegral();
192       Integer.Type = Other.Integer.Type;
193       return *this;
194     } 
195
196     // Destroy the current integral value, if that's what we're holding.
197     if (Kind == Integral)
198       getAsIntegral()->~APSInt();
199
200     Kind = Other.Kind;
201
202     if (Other.Kind == Integral) {
203       new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
204       Integer.Type = Other.Integer.Type;
205     } else if (Other.Kind == Pack) {
206       Args.NumArgs = Other.Args.NumArgs;
207       Args.Args = Other.Args.Args;
208     } else if (Kind == Template || Kind == TemplateExpansion) {
209       TemplateArg.Name = Other.TemplateArg.Name;
210       TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions;
211     } else {
212       TypeOrValue = Other.TypeOrValue;
213     }
214
215     return *this;
216   }
217
218   ~TemplateArgument() {
219     using llvm::APSInt;
220
221     if (Kind == Integral)
222       getAsIntegral()->~APSInt();
223   }
224
225   /// \brief Create a new template argument pack by copying the given set of
226   /// template arguments.
227   static TemplateArgument CreatePackCopy(ASTContext &Context,
228                                          const TemplateArgument *Args,
229                                          unsigned NumArgs);
230   
231   /// \brief Return the kind of stored template argument.
232   ArgKind getKind() const { return (ArgKind)Kind; }
233
234   /// \brief Determine whether this template argument has no value.
235   bool isNull() const { return Kind == Null; }
236
237   /// \brief Whether this template argument is dependent on a template
238   /// parameter such that its result can change from one instantiation to
239   /// another.
240   bool isDependent() const;
241
242   /// \brief Whether this template argument is dependent on a template
243   /// parameter.
244   bool isInstantiationDependent() const;
245
246   /// \brief Whether this template argument contains an unexpanded
247   /// parameter pack.
248   bool containsUnexpandedParameterPack() const;
249
250   /// \brief Determine whether this template argument is a pack expansion.
251   bool isPackExpansion() const;
252   
253   /// \brief Retrieve the template argument as a type.
254   QualType getAsType() const {
255     if (Kind != Type)
256       return QualType();
257
258     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
259   }
260
261   /// \brief Retrieve the template argument as a declaration.
262   Decl *getAsDecl() const {
263     if (Kind != Declaration)
264       return 0;
265     return reinterpret_cast<Decl *>(TypeOrValue);
266   }
267
268   /// \brief Retrieve the template argument as a template name.
269   TemplateName getAsTemplate() const {
270     if (Kind != Template)
271       return TemplateName();
272     
273     return TemplateName::getFromVoidPointer(TemplateArg.Name);
274   }
275
276   /// \brief Retrieve the template argument as a template name; if the argument
277   /// is a pack expansion, return the pattern as a template name.
278   TemplateName getAsTemplateOrTemplatePattern() const {
279     if (Kind != Template && Kind != TemplateExpansion)
280       return TemplateName();
281     
282     return TemplateName::getFromVoidPointer(TemplateArg.Name);
283   }
284
285   /// \brief Retrieve the number of expansions that a template template argument
286   /// expansion will produce, if known.
287   llvm::Optional<unsigned> getNumTemplateExpansions() const;
288   
289   /// \brief Retrieve the template argument as an integral value.
290   llvm::APSInt *getAsIntegral() {
291     if (Kind != Integral)
292       return 0;
293     return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
294   }
295
296   const llvm::APSInt *getAsIntegral() const {
297     return const_cast<TemplateArgument*>(this)->getAsIntegral();
298   }
299
300   /// \brief Retrieve the type of the integral value.
301   QualType getIntegralType() const {
302     if (Kind != Integral)
303       return QualType();
304
305     return QualType::getFromOpaquePtr(Integer.Type);
306   }
307
308   void setIntegralType(QualType T) {
309     assert(Kind == Integral &&
310            "Cannot set the integral type of a non-integral template argument");
311     Integer.Type = T.getAsOpaquePtr();
312   }
313
314   /// \brief Retrieve the template argument as an expression.
315   Expr *getAsExpr() const {
316     if (Kind != Expression)
317       return 0;
318
319     return reinterpret_cast<Expr *>(TypeOrValue);
320   }
321
322   /// \brief Iterator that traverses the elements of a template argument pack.
323   typedef const TemplateArgument * pack_iterator;
324
325   /// \brief Iterator referencing the first argument of a template argument
326   /// pack.
327   pack_iterator pack_begin() const {
328     assert(Kind == Pack);
329     return Args.Args;
330   }
331
332   /// \brief Iterator referencing one past the last argument of a template
333   /// argument pack.
334   pack_iterator pack_end() const {
335     assert(Kind == Pack);
336     return Args.Args + Args.NumArgs;
337   }
338
339   /// \brief The number of template arguments in the given template argument
340   /// pack.
341   unsigned pack_size() const {
342     assert(Kind == Pack);
343     return Args.NumArgs;
344   }
345
346   /// Determines whether two template arguments are superficially the
347   /// same.
348   bool structurallyEquals(const TemplateArgument &Other) const;
349
350   /// \brief When the template argument is a pack expansion, returns 
351   /// the pattern of the pack expansion.
352   ///
353   /// \param Ellipsis Will be set to the location of the ellipsis.
354   TemplateArgument getPackExpansionPattern() const;
355
356   /// \brief Print this template argument to the given output stream.
357   void print(const PrintingPolicy &Policy, llvm::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   union {
367     Expr *Expression;
368     TypeSourceInfo *Declarator;
369     struct {
370       // FIXME: We'd like to just use the qualifier in the TemplateName,
371       // but template arguments get canonicalized too quickly.
372       NestedNameSpecifier *Qualifier;
373       void *QualifierLocData;
374       unsigned TemplateNameLoc;
375       unsigned EllipsisLoc;
376     } Template;
377   };
378
379 public:
380   TemplateArgumentLocInfo();
381   
382   TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
383   
384   TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
385   
386   TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
387                           SourceLocation TemplateNameLoc,
388                           SourceLocation EllipsisLoc)
389   {
390     Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
391     Template.QualifierLocData = QualifierLoc.getOpaqueData();
392     Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
393     Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
394   }
395
396   TypeSourceInfo *getAsTypeSourceInfo() const {
397     return Declarator;
398   }
399
400   Expr *getAsExpr() const {
401     return Expression;
402   }
403
404   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
405     return NestedNameSpecifierLoc(Template.Qualifier, 
406                                   Template.QualifierLocData);
407   }
408   
409   SourceLocation getTemplateNameLoc() const {
410     return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
411   }
412   
413   SourceLocation getTemplateEllipsisLoc() const {
414     return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
415   }
416 };
417
418 /// Location wrapper for a TemplateArgument.  TemplateArgument is to
419 /// TemplateArgumentLoc as Type is to TypeLoc.
420 class TemplateArgumentLoc {
421   TemplateArgument Argument;
422   TemplateArgumentLocInfo LocInfo;
423
424 public:
425   TemplateArgumentLoc() {}
426
427   TemplateArgumentLoc(const TemplateArgument &Argument,
428                       TemplateArgumentLocInfo Opaque)
429     : Argument(Argument), LocInfo(Opaque) {
430   }
431
432   TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
433     : Argument(Argument), LocInfo(TInfo) {
434     assert(Argument.getKind() == TemplateArgument::Type);
435   }
436
437   TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
438     : Argument(Argument), LocInfo(E) {
439     assert(Argument.getKind() == TemplateArgument::Expression);
440   }
441
442   TemplateArgumentLoc(const TemplateArgument &Argument, 
443                       NestedNameSpecifierLoc QualifierLoc,
444                       SourceLocation TemplateNameLoc,
445                       SourceLocation EllipsisLoc = SourceLocation())
446     : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
447     assert(Argument.getKind() == TemplateArgument::Template ||
448            Argument.getKind() == TemplateArgument::TemplateExpansion);
449   }
450   
451   /// \brief - Fetches the primary location of the argument.
452   SourceLocation getLocation() const {
453     if (Argument.getKind() == TemplateArgument::Template ||
454         Argument.getKind() == TemplateArgument::TemplateExpansion)
455       return getTemplateNameLoc();
456     
457     return getSourceRange().getBegin();
458   }
459
460   /// \brief - Fetches the full source range of the argument.
461   SourceRange getSourceRange() const;
462
463   const TemplateArgument &getArgument() const {
464     return Argument;
465   }
466
467   TemplateArgumentLocInfo getLocInfo() const {
468     return LocInfo;
469   }
470
471   TypeSourceInfo *getTypeSourceInfo() const {
472     assert(Argument.getKind() == TemplateArgument::Type);
473     return LocInfo.getAsTypeSourceInfo();
474   }
475
476   Expr *getSourceExpression() const {
477     assert(Argument.getKind() == TemplateArgument::Expression);
478     return LocInfo.getAsExpr();
479   }
480
481   Expr *getSourceDeclExpression() const {
482     assert(Argument.getKind() == TemplateArgument::Declaration);
483     return LocInfo.getAsExpr();
484   }
485   
486   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
487     assert(Argument.getKind() == TemplateArgument::Template ||
488            Argument.getKind() == TemplateArgument::TemplateExpansion);
489     return LocInfo.getTemplateQualifierLoc();
490   }
491   
492   SourceLocation getTemplateNameLoc() const {
493     assert(Argument.getKind() == TemplateArgument::Template ||
494            Argument.getKind() == TemplateArgument::TemplateExpansion);
495     return LocInfo.getTemplateNameLoc();
496   }  
497   
498   SourceLocation getTemplateEllipsisLoc() const {
499     assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
500     return LocInfo.getTemplateEllipsisLoc();
501   }
502   
503   /// \brief When the template argument is a pack expansion, returns 
504   /// the pattern of the pack expansion.
505   ///
506   /// \param Ellipsis Will be set to the location of the ellipsis.
507   ///
508   /// \param NumExpansions Will be set to the number of expansions that will
509   /// be generated from this pack expansion, if known a priori.
510   TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
511                                         llvm::Optional<unsigned> &NumExpansions,
512                                               ASTContext &Context) const;
513 };
514
515 /// A convenient class for passing around template argument
516 /// information.  Designed to be passed by reference.
517 class TemplateArgumentListInfo {
518   llvm::SmallVector<TemplateArgumentLoc, 8> Arguments;
519   SourceLocation LAngleLoc;
520   SourceLocation RAngleLoc;
521
522 public:
523   TemplateArgumentListInfo() {}
524
525   TemplateArgumentListInfo(SourceLocation LAngleLoc,
526                            SourceLocation RAngleLoc)
527     : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
528
529   SourceLocation getLAngleLoc() const { return LAngleLoc; }
530   SourceLocation getRAngleLoc() const { return RAngleLoc; }
531
532   void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
533   void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
534
535   unsigned size() const { return Arguments.size(); }
536
537   const TemplateArgumentLoc *getArgumentArray() const {
538     return Arguments.data();
539   }
540
541   const TemplateArgumentLoc &operator[](unsigned I) const {
542     return Arguments[I];
543   }
544
545   void addArgument(const TemplateArgumentLoc &Loc) {
546     Arguments.push_back(Loc);
547   }
548 };
549
550 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
551                                     const TemplateArgument &Arg);
552
553 inline TemplateSpecializationType::iterator
554     TemplateSpecializationType::end() const {
555   return getArgs() + getNumArgs();
556 }
557
558 inline DependentTemplateSpecializationType::iterator
559     DependentTemplateSpecializationType::end() const {
560   return getArgs() + getNumArgs();
561 }
562
563 inline const TemplateArgument &
564     TemplateSpecializationType::getArg(unsigned Idx) const {
565   assert(Idx < getNumArgs() && "Template argument out of range");
566   return getArgs()[Idx];
567 }
568
569 inline const TemplateArgument &
570     DependentTemplateSpecializationType::getArg(unsigned Idx) const {
571   assert(Idx < getNumArgs() && "Template argument out of range");
572   return getArgs()[Idx];
573 }
574   
575 } // end namespace clang
576
577 #endif