TemplateBase.h revision efce31f51d6e7e31e125f96c20f6cdab3ead0a47
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    using namespace llvm;
248    if (Integer.BitWidth <= 64)
249      return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
250
251    unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
252    return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
253                  Integer.IsUnsigned);
254  }
255
256  /// \brief Retrieve the type of the integral value.
257  QualType getIntegralType() const {
258    if (Kind != Integral)
259      return QualType();
260
261    return QualType::getFromOpaquePtr(Integer.Type);
262  }
263
264  void setIntegralType(QualType T) {
265    assert(Kind == Integral &&
266           "Cannot set the integral type of a non-integral template argument");
267    Integer.Type = T.getAsOpaquePtr();
268  }
269
270  /// \brief Retrieve the template argument as an expression.
271  Expr *getAsExpr() const {
272    if (Kind != Expression)
273      return 0;
274
275    return reinterpret_cast<Expr *>(TypeOrValue);
276  }
277
278  /// \brief Iterator that traverses the elements of a template argument pack.
279  typedef const TemplateArgument * pack_iterator;
280
281  /// \brief Iterator referencing the first argument of a template argument
282  /// pack.
283  pack_iterator pack_begin() const {
284    assert(Kind == Pack);
285    return Args.Args;
286  }
287
288  /// \brief Iterator referencing one past the last argument of a template
289  /// argument pack.
290  pack_iterator pack_end() const {
291    assert(Kind == Pack);
292    return Args.Args + Args.NumArgs;
293  }
294
295  /// \brief The number of template arguments in the given template argument
296  /// pack.
297  unsigned pack_size() const {
298    assert(Kind == Pack);
299    return Args.NumArgs;
300  }
301
302  /// \brief Determines whether two template arguments are superficially the
303  /// same.
304  bool structurallyEquals(const TemplateArgument &Other) const;
305
306  /// \brief When the template argument is a pack expansion, returns
307  /// the pattern of the pack expansion.
308  TemplateArgument getPackExpansionPattern() const;
309
310  /// \brief Print this template argument to the given output stream.
311  void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
312
313  /// \brief Used to insert TemplateArguments into FoldingSets.
314  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
315};
316
317/// Location information for a TemplateArgument.
318struct TemplateArgumentLocInfo {
319private:
320  union {
321    Expr *Expression;
322    TypeSourceInfo *Declarator;
323    struct {
324      // FIXME: We'd like to just use the qualifier in the TemplateName,
325      // but template arguments get canonicalized too quickly.
326      NestedNameSpecifier *Qualifier;
327      void *QualifierLocData;
328      unsigned TemplateNameLoc;
329      unsigned EllipsisLoc;
330    } Template;
331  };
332
333public:
334  TemplateArgumentLocInfo();
335
336  TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
337
338  TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
339
340  TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
341                          SourceLocation TemplateNameLoc,
342                          SourceLocation EllipsisLoc)
343  {
344    Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
345    Template.QualifierLocData = QualifierLoc.getOpaqueData();
346    Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
347    Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
348  }
349
350  TypeSourceInfo *getAsTypeSourceInfo() const {
351    return Declarator;
352  }
353
354  Expr *getAsExpr() const {
355    return Expression;
356  }
357
358  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
359    return NestedNameSpecifierLoc(Template.Qualifier,
360                                  Template.QualifierLocData);
361  }
362
363  SourceLocation getTemplateNameLoc() const {
364    return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
365  }
366
367  SourceLocation getTemplateEllipsisLoc() const {
368    return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
369  }
370};
371
372/// Location wrapper for a TemplateArgument.  TemplateArgument is to
373/// TemplateArgumentLoc as Type is to TypeLoc.
374class TemplateArgumentLoc {
375  TemplateArgument Argument;
376  TemplateArgumentLocInfo LocInfo;
377
378public:
379  TemplateArgumentLoc() {}
380
381  TemplateArgumentLoc(const TemplateArgument &Argument,
382                      TemplateArgumentLocInfo Opaque)
383    : Argument(Argument), LocInfo(Opaque) {
384  }
385
386  TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
387    : Argument(Argument), LocInfo(TInfo) {
388    assert(Argument.getKind() == TemplateArgument::Type);
389  }
390
391  TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
392    : Argument(Argument), LocInfo(E) {
393    assert(Argument.getKind() == TemplateArgument::Expression);
394  }
395
396  TemplateArgumentLoc(const TemplateArgument &Argument,
397                      NestedNameSpecifierLoc QualifierLoc,
398                      SourceLocation TemplateNameLoc,
399                      SourceLocation EllipsisLoc = SourceLocation())
400    : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
401    assert(Argument.getKind() == TemplateArgument::Template ||
402           Argument.getKind() == TemplateArgument::TemplateExpansion);
403  }
404
405  /// \brief - Fetches the primary location of the argument.
406  SourceLocation getLocation() const {
407    if (Argument.getKind() == TemplateArgument::Template ||
408        Argument.getKind() == TemplateArgument::TemplateExpansion)
409      return getTemplateNameLoc();
410
411    return getSourceRange().getBegin();
412  }
413
414  /// \brief - Fetches the full source range of the argument.
415  SourceRange getSourceRange() const LLVM_READONLY;
416
417  const TemplateArgument &getArgument() const {
418    return Argument;
419  }
420
421  TemplateArgumentLocInfo getLocInfo() const {
422    return LocInfo;
423  }
424
425  TypeSourceInfo *getTypeSourceInfo() const {
426    assert(Argument.getKind() == TemplateArgument::Type);
427    return LocInfo.getAsTypeSourceInfo();
428  }
429
430  Expr *getSourceExpression() const {
431    assert(Argument.getKind() == TemplateArgument::Expression);
432    return LocInfo.getAsExpr();
433  }
434
435  Expr *getSourceDeclExpression() const {
436    assert(Argument.getKind() == TemplateArgument::Declaration);
437    return LocInfo.getAsExpr();
438  }
439
440  NestedNameSpecifierLoc getTemplateQualifierLoc() const {
441    assert(Argument.getKind() == TemplateArgument::Template ||
442           Argument.getKind() == TemplateArgument::TemplateExpansion);
443    return LocInfo.getTemplateQualifierLoc();
444  }
445
446  SourceLocation getTemplateNameLoc() const {
447    assert(Argument.getKind() == TemplateArgument::Template ||
448           Argument.getKind() == TemplateArgument::TemplateExpansion);
449    return LocInfo.getTemplateNameLoc();
450  }
451
452  SourceLocation getTemplateEllipsisLoc() const {
453    assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
454    return LocInfo.getTemplateEllipsisLoc();
455  }
456
457  /// \brief When the template argument is a pack expansion, returns
458  /// the pattern of the pack expansion.
459  ///
460  /// \param Ellipsis Will be set to the location of the ellipsis.
461  ///
462  /// \param NumExpansions Will be set to the number of expansions that will
463  /// be generated from this pack expansion, if known a priori.
464  TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
465                                        llvm::Optional<unsigned> &NumExpansions,
466                                              ASTContext &Context) const;
467};
468
469/// A convenient class for passing around template argument
470/// information.  Designed to be passed by reference.
471class TemplateArgumentListInfo {
472  SmallVector<TemplateArgumentLoc, 8> Arguments;
473  SourceLocation LAngleLoc;
474  SourceLocation RAngleLoc;
475
476  // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
477  // instead.
478  void* operator new(size_t bytes, ASTContext& C);
479
480public:
481  TemplateArgumentListInfo() {}
482
483  TemplateArgumentListInfo(SourceLocation LAngleLoc,
484                           SourceLocation RAngleLoc)
485    : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
486
487  SourceLocation getLAngleLoc() const { return LAngleLoc; }
488  SourceLocation getRAngleLoc() const { return RAngleLoc; }
489
490  void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
491  void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
492
493  unsigned size() const { return Arguments.size(); }
494
495  const TemplateArgumentLoc *getArgumentArray() const {
496    return Arguments.data();
497  }
498
499  const TemplateArgumentLoc &operator[](unsigned I) const {
500    return Arguments[I];
501  }
502
503  void addArgument(const TemplateArgumentLoc &Loc) {
504    Arguments.push_back(Loc);
505  }
506};
507
508/// \brief Represents an explicit template argument list in C++, e.g.,
509/// the "<int>" in "sort<int>".
510/// This is safe to be used inside an AST node, in contrast with
511/// TemplateArgumentListInfo.
512struct ASTTemplateArgumentListInfo {
513  /// \brief The source location of the left angle bracket ('<');
514  SourceLocation LAngleLoc;
515
516  /// \brief The source location of the right angle bracket ('>');
517  SourceLocation RAngleLoc;
518
519  /// \brief The number of template arguments in TemplateArgs.
520  /// The actual template arguments (if any) are stored after the
521  /// ExplicitTemplateArgumentList structure.
522  unsigned NumTemplateArgs;
523
524  /// \brief Retrieve the template arguments
525  TemplateArgumentLoc *getTemplateArgs() {
526    return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
527  }
528
529  /// \brief Retrieve the template arguments
530  const TemplateArgumentLoc *getTemplateArgs() const {
531    return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
532  }
533
534  const TemplateArgumentLoc &operator[](unsigned I) const {
535    return getTemplateArgs()[I];
536  }
537
538  static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
539                                          const TemplateArgumentListInfo &List);
540
541  void initializeFrom(const TemplateArgumentListInfo &List);
542  void initializeFrom(const TemplateArgumentListInfo &List,
543                      bool &Dependent, bool &InstantiationDependent,
544                      bool &ContainsUnexpandedParameterPack);
545  void copyInto(TemplateArgumentListInfo &List) const;
546  static std::size_t sizeFor(unsigned NumTemplateArgs);
547};
548
549/// \brief Extends ASTTemplateArgumentListInfo with the source location
550/// information for the template keyword; this is used as part of the
551/// representation of qualified identifiers, such as S<T>::template apply<T>.
552struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo {
553  typedef ASTTemplateArgumentListInfo Base;
554
555  // NOTE: the source location of the (optional) template keyword is
556  // stored after all template arguments.
557
558  /// \brief Get the source location of the template keyword.
559  SourceLocation getTemplateKeywordLoc() const {
560    return *reinterpret_cast<const SourceLocation*>
561      (getTemplateArgs() + NumTemplateArgs);
562  }
563
564  /// \brief Sets the source location of the template keyword.
565  void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) {
566    *reinterpret_cast<SourceLocation*>
567      (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc;
568  }
569
570  static const ASTTemplateKWAndArgsInfo*
571  Create(ASTContext &C, SourceLocation TemplateKWLoc,
572         const TemplateArgumentListInfo &List);
573
574  void initializeFrom(SourceLocation TemplateKWLoc,
575                      const TemplateArgumentListInfo &List);
576  void initializeFrom(SourceLocation TemplateKWLoc,
577                      const TemplateArgumentListInfo &List,
578                      bool &Dependent, bool &InstantiationDependent,
579                      bool &ContainsUnexpandedParameterPack);
580  void initializeFrom(SourceLocation TemplateKWLoc);
581
582  static std::size_t sizeFor(unsigned NumTemplateArgs);
583};
584
585const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
586                                    const TemplateArgument &Arg);
587
588inline TemplateSpecializationType::iterator
589    TemplateSpecializationType::end() const {
590  return getArgs() + getNumArgs();
591}
592
593inline DependentTemplateSpecializationType::iterator
594    DependentTemplateSpecializationType::end() const {
595  return getArgs() + getNumArgs();
596}
597
598inline const TemplateArgument &
599    TemplateSpecializationType::getArg(unsigned Idx) const {
600  assert(Idx < getNumArgs() && "Template argument out of range");
601  return getArgs()[Idx];
602}
603
604inline const TemplateArgument &
605    DependentTemplateSpecializationType::getArg(unsigned Idx) const {
606  assert(Idx < getNumArgs() && "Template argument out of range");
607  return getArgs()[Idx];
608}
609
610} // end namespace clang
611
612#endif
613