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