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