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