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