TemplateBase.h revision e2e1fa27e2533410f744137b0db1bc9491543392
1//===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file provides definitions which are common for all kinds of
11//  template representation.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
16#define LLVM_CLANG_AST_TEMPLATEBASE_H
17
18#include "clang/AST/TemplateName.h"
19#include "clang/AST/Type.h"
20#include "llvm/ADT/APSInt.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/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) LLVM_DELETED_FUNCTION;
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, 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  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 Return the array of arguments in this template argument pack.
321  llvm::ArrayRef<TemplateArgument> getPackAsArray() const {
322    assert(Kind == Pack);
323    return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
324  }
325
326  /// \brief Determines whether two template arguments are superficially the
327  /// same.
328  bool structurallyEquals(const TemplateArgument &Other) const;
329
330  /// \brief When the template argument is a pack expansion, returns
331  /// the pattern of the pack expansion.
332  TemplateArgument getPackExpansionPattern() const;
333
334  /// \brief Print this template argument to the given output stream.
335  void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
336
337  /// \brief Used to insert TemplateArguments into FoldingSets.
338  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
339};
340
341/// Location information for a TemplateArgument.
342struct TemplateArgumentLocInfo {
343private:
344  union {
345    Expr *Expression;
346    TypeSourceInfo *Declarator;
347    struct {
348      // FIXME: We'd like to just use the qualifier in the TemplateName,
349      // but template arguments get canonicalized too quickly.
350      NestedNameSpecifier *Qualifier;
351      void *QualifierLocData;
352      unsigned TemplateNameLoc;
353      unsigned EllipsisLoc;
354    } Template;
355  };
356
357public:
358  TemplateArgumentLocInfo();
359
360  TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
361
362  TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
363
364  TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
365                          SourceLocation TemplateNameLoc,
366                          SourceLocation EllipsisLoc)
367  {
368    Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
369    Template.QualifierLocData = QualifierLoc.getOpaqueData();
370    Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
371    Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
372  }
373
374  TypeSourceInfo *getAsTypeSourceInfo() const {
375    return Declarator;
376  }
377
378  Expr *getAsExpr() const {
379    return Expression;
380  }
381
382  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
383    return NestedNameSpecifierLoc(Template.Qualifier,
384                                  Template.QualifierLocData);
385  }
386
387  SourceLocation getTemplateNameLoc() const {
388    return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
389  }
390
391  SourceLocation getTemplateEllipsisLoc() const {
392    return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
393  }
394};
395
396/// Location wrapper for a TemplateArgument.  TemplateArgument is to
397/// TemplateArgumentLoc as Type is to TypeLoc.
398class TemplateArgumentLoc {
399  TemplateArgument Argument;
400  TemplateArgumentLocInfo LocInfo;
401
402public:
403  TemplateArgumentLoc() {}
404
405  TemplateArgumentLoc(const TemplateArgument &Argument,
406                      TemplateArgumentLocInfo Opaque)
407    : Argument(Argument), LocInfo(Opaque) {
408  }
409
410  TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
411    : Argument(Argument), LocInfo(TInfo) {
412    assert(Argument.getKind() == TemplateArgument::Type);
413  }
414
415  TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
416    : Argument(Argument), LocInfo(E) {
417    assert(Argument.getKind() == TemplateArgument::Expression);
418  }
419
420  TemplateArgumentLoc(const TemplateArgument &Argument,
421                      NestedNameSpecifierLoc QualifierLoc,
422                      SourceLocation TemplateNameLoc,
423                      SourceLocation EllipsisLoc = SourceLocation())
424    : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
425    assert(Argument.getKind() == TemplateArgument::Template ||
426           Argument.getKind() == TemplateArgument::TemplateExpansion);
427  }
428
429  /// \brief - Fetches the primary location of the argument.
430  SourceLocation getLocation() const {
431    if (Argument.getKind() == TemplateArgument::Template ||
432        Argument.getKind() == TemplateArgument::TemplateExpansion)
433      return getTemplateNameLoc();
434
435    return getSourceRange().getBegin();
436  }
437
438  /// \brief - Fetches the full source range of the argument.
439  SourceRange getSourceRange() const LLVM_READONLY;
440
441  const TemplateArgument &getArgument() const {
442    return Argument;
443  }
444
445  TemplateArgumentLocInfo getLocInfo() const {
446    return LocInfo;
447  }
448
449  TypeSourceInfo *getTypeSourceInfo() const {
450    assert(Argument.getKind() == TemplateArgument::Type);
451    return LocInfo.getAsTypeSourceInfo();
452  }
453
454  Expr *getSourceExpression() const {
455    assert(Argument.getKind() == TemplateArgument::Expression);
456    return LocInfo.getAsExpr();
457  }
458
459  Expr *getSourceDeclExpression() const {
460    assert(Argument.getKind() == TemplateArgument::Declaration);
461    return LocInfo.getAsExpr();
462  }
463
464  Expr *getSourceNullPtrExpression() const {
465    assert(Argument.getKind() == TemplateArgument::NullPtr);
466    return LocInfo.getAsExpr();
467  }
468
469  Expr *getSourceIntegralExpression() const {
470    assert(Argument.getKind() == TemplateArgument::Integral);
471    return LocInfo.getAsExpr();
472  }
473
474  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
475    assert(Argument.getKind() == TemplateArgument::Template ||
476           Argument.getKind() == TemplateArgument::TemplateExpansion);
477    return LocInfo.getTemplateQualifierLoc();
478  }
479
480  SourceLocation getTemplateNameLoc() const {
481    assert(Argument.getKind() == TemplateArgument::Template ||
482           Argument.getKind() == TemplateArgument::TemplateExpansion);
483    return LocInfo.getTemplateNameLoc();
484  }
485
486  SourceLocation getTemplateEllipsisLoc() const {
487    assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
488    return LocInfo.getTemplateEllipsisLoc();
489  }
490
491  /// \brief When the template argument is a pack expansion, returns
492  /// the pattern of the pack expansion.
493  ///
494  /// \param Ellipsis Will be set to the location of the ellipsis.
495  ///
496  /// \param NumExpansions Will be set to the number of expansions that will
497  /// be generated from this pack expansion, if known a priori.
498  TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
499                                              Optional<unsigned> &NumExpansions,
500                                              ASTContext &Context) const;
501};
502
503/// A convenient class for passing around template argument
504/// information.  Designed to be passed by reference.
505class TemplateArgumentListInfo {
506  SmallVector<TemplateArgumentLoc, 8> Arguments;
507  SourceLocation LAngleLoc;
508  SourceLocation RAngleLoc;
509
510  // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
511  // instead.
512  void* operator new(size_t bytes, ASTContext& C);
513
514public:
515  TemplateArgumentListInfo() {}
516
517  TemplateArgumentListInfo(SourceLocation LAngleLoc,
518                           SourceLocation RAngleLoc)
519    : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
520
521  SourceLocation getLAngleLoc() const { return LAngleLoc; }
522  SourceLocation getRAngleLoc() const { return RAngleLoc; }
523
524  void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
525  void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
526
527  unsigned size() const { return Arguments.size(); }
528
529  const TemplateArgumentLoc *getArgumentArray() const {
530    return Arguments.data();
531  }
532
533  const TemplateArgumentLoc &operator[](unsigned I) const {
534    return Arguments[I];
535  }
536
537  void addArgument(const TemplateArgumentLoc &Loc) {
538    Arguments.push_back(Loc);
539  }
540};
541
542/// \brief Represents an explicit template argument list in C++, e.g.,
543/// the "<int>" in "sort<int>".
544/// This is safe to be used inside an AST node, in contrast with
545/// TemplateArgumentListInfo.
546struct ASTTemplateArgumentListInfo {
547  /// \brief The source location of the left angle bracket ('<').
548  SourceLocation LAngleLoc;
549
550  /// \brief The source location of the right angle bracket ('>').
551  SourceLocation RAngleLoc;
552
553  union {
554    /// \brief The number of template arguments in TemplateArgs.
555    /// The actual template arguments (if any) are stored after the
556    /// ExplicitTemplateArgumentList structure.
557    unsigned NumTemplateArgs;
558
559    /// Force ASTTemplateArgumentListInfo to the right alignment
560    /// for the following array of TemplateArgumentLocs.
561    void *Aligner;
562  };
563
564  /// \brief Retrieve the template arguments
565  TemplateArgumentLoc *getTemplateArgs() {
566    return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
567  }
568
569  /// \brief Retrieve the template arguments
570  const TemplateArgumentLoc *getTemplateArgs() const {
571    return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
572  }
573
574  const TemplateArgumentLoc &operator[](unsigned I) const {
575    return getTemplateArgs()[I];
576  }
577
578  static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
579                                          const TemplateArgumentListInfo &List);
580
581  void initializeFrom(const TemplateArgumentListInfo &List);
582  void initializeFrom(const TemplateArgumentListInfo &List,
583                      bool &Dependent, bool &InstantiationDependent,
584                      bool &ContainsUnexpandedParameterPack);
585  void copyInto(TemplateArgumentListInfo &List) const;
586  static std::size_t sizeFor(unsigned NumTemplateArgs);
587};
588
589/// \brief Extends ASTTemplateArgumentListInfo with the source location
590/// information for the template keyword; this is used as part of the
591/// representation of qualified identifiers, such as S<T>::template apply<T>.
592struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo {
593  typedef ASTTemplateArgumentListInfo Base;
594
595  // NOTE: the source location of the (optional) template keyword is
596  // stored after all template arguments.
597
598  /// \brief Get the source location of the template keyword.
599  SourceLocation getTemplateKeywordLoc() const {
600    return *reinterpret_cast<const SourceLocation*>
601      (getTemplateArgs() + NumTemplateArgs);
602  }
603
604  /// \brief Sets the source location of the template keyword.
605  void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) {
606    *reinterpret_cast<SourceLocation*>
607      (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc;
608  }
609
610  static const ASTTemplateKWAndArgsInfo*
611  Create(ASTContext &C, SourceLocation TemplateKWLoc,
612         const TemplateArgumentListInfo &List);
613
614  void initializeFrom(SourceLocation TemplateKWLoc,
615                      const TemplateArgumentListInfo &List);
616  void initializeFrom(SourceLocation TemplateKWLoc,
617                      const TemplateArgumentListInfo &List,
618                      bool &Dependent, bool &InstantiationDependent,
619                      bool &ContainsUnexpandedParameterPack);
620  void initializeFrom(SourceLocation TemplateKWLoc);
621
622  static std::size_t sizeFor(unsigned NumTemplateArgs);
623};
624
625const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
626                                    const TemplateArgument &Arg);
627
628inline TemplateSpecializationType::iterator
629    TemplateSpecializationType::end() const {
630  return getArgs() + getNumArgs();
631}
632
633inline DependentTemplateSpecializationType::iterator
634    DependentTemplateSpecializationType::end() const {
635  return getArgs() + getNumArgs();
636}
637
638inline const TemplateArgument &
639    TemplateSpecializationType::getArg(unsigned Idx) const {
640  assert(Idx < getNumArgs() && "Template argument out of range");
641  return getArgs()[Idx];
642}
643
644inline const TemplateArgument &
645    DependentTemplateSpecializationType::getArg(unsigned Idx) const {
646  assert(Idx < getNumArgs() && "Template argument out of range");
647  return getArgs()[Idx];
648}
649
650} // end namespace clang
651
652#endif
653