TemplateBase.h revision d3731198193eee92796ddeb493973b7a598b003e
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 "llvm/ADT/APSInt.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "clang/AST/Type.h"
22#include "clang/AST/TemplateName.h"
23
24namespace llvm {
25  class FoldingSetNodeID;
26  class raw_ostream;
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  };
84
85public:
86  /// \brief Construct an empty, invalid template argument.
87  TemplateArgument() : Kind(Null), TypeOrValue(0) { }
88
89  /// \brief Construct a template type argument.
90  TemplateArgument(QualType T) : Kind(Type) {
91    TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
92  }
93
94  /// \brief Construct a template argument that refers to a
95  /// declaration, which is either an external declaration or a
96  /// template declaration.
97  TemplateArgument(Decl *D) : Kind(Declaration) {
98    // FIXME: Need to be sure we have the "canonical" declaration!
99    TypeOrValue = reinterpret_cast<uintptr_t>(D);
100  }
101
102  /// \brief Construct an integral constant template argument.
103  TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) {
104    // FIXME: Large integral values will get leaked. Do something
105    // similar to what we did with IntegerLiteral.
106    new (Integer.Value) llvm::APSInt(Value);
107    Integer.Type = Type.getAsOpaquePtr();
108  }
109
110  /// \brief Construct a template argument that is a template or a pack
111  /// expansion of templates.
112  ///
113  /// This form of template argument is generally used for template template
114  /// parameters. However, the template name could be a dependent template
115  /// name that ends up being instantiated to a function template whose address
116  /// is taken.
117  ///
118  /// \param Name The template name.
119  /// \param PackExpansion Whether this template argument is a pack expansion.
120  TemplateArgument(TemplateName Name, bool PackExpansion = false)
121    : Kind(PackExpansion? TemplateExpansion : Template)
122  {
123    TypeOrValue = reinterpret_cast<uintptr_t>(Name.getAsVoidPointer());
124  }
125
126  /// \brief Construct a template argument that is an expression.
127  ///
128  /// This form of template argument only occurs in template argument
129  /// lists used for dependent types and for expression; it will not
130  /// occur in a non-dependent, canonical template argument list.
131  TemplateArgument(Expr *E) : Kind(Expression) {
132    TypeOrValue = reinterpret_cast<uintptr_t>(E);
133  }
134
135  /// \brief Construct a template argument that is a template argument pack.
136  ///
137  /// We assume that storage for the template arguments provided
138  /// outlives the TemplateArgument itself.
139  TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){
140    this->Args.Args = Args;
141    this->Args.NumArgs = NumArgs;
142  }
143
144  /// \brief Copy constructor for a template argument.
145  TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
146    // FIXME: Large integral values will get leaked. Do something
147    // similar to what we did with IntegerLiteral.
148    if (Kind == Integral) {
149      new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
150      Integer.Type = Other.Integer.Type;
151    } else if (Kind == Pack) {
152      Args.NumArgs = Other.Args.NumArgs;
153      Args.Args = Other.Args.Args;
154    } else
155      TypeOrValue = Other.TypeOrValue;
156  }
157
158  TemplateArgument& operator=(const TemplateArgument& Other) {
159    using llvm::APSInt;
160
161    if (Kind == Other.Kind && Kind == Integral) {
162      // Copy integral values.
163      *this->getAsIntegral() = *Other.getAsIntegral();
164      Integer.Type = Other.Integer.Type;
165      return *this;
166    }
167
168    // Destroy the current integral value, if that's what we're holding.
169    if (Kind == Integral)
170      getAsIntegral()->~APSInt();
171
172    Kind = Other.Kind;
173
174    if (Other.Kind == Integral) {
175      new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
176      Integer.Type = Other.Integer.Type;
177    } else if (Other.Kind == Pack) {
178      Args.NumArgs = Other.Args.NumArgs;
179      Args.Args = Other.Args.Args;
180    } else {
181      TypeOrValue = Other.TypeOrValue;
182    }
183
184    return *this;
185  }
186
187  ~TemplateArgument() {
188    using llvm::APSInt;
189
190    if (Kind == Integral)
191      getAsIntegral()->~APSInt();
192  }
193
194  /// \brief Return the kind of stored template argument.
195  ArgKind getKind() const { return (ArgKind)Kind; }
196
197  /// \brief Determine whether this template argument has no value.
198  bool isNull() const { return Kind == Null; }
199
200  /// \brief Whether this template argument is dependent on a template
201  /// parameter.
202  bool isDependent() const;
203
204  /// \brief Whether this template argument contains an unexpanded
205  /// parameter pack.
206  bool containsUnexpandedParameterPack() const;
207
208  /// \brief Determine whether this template argument is a pack expansion.
209  bool isPackExpansion() const;
210
211  /// \brief Retrieve the template argument as a type.
212  QualType getAsType() const {
213    if (Kind != Type)
214      return QualType();
215
216    return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue));
217  }
218
219  /// \brief Retrieve the template argument as a declaration.
220  Decl *getAsDecl() const {
221    if (Kind != Declaration)
222      return 0;
223    return reinterpret_cast<Decl *>(TypeOrValue);
224  }
225
226  /// \brief Retrieve the template argument as a template name.
227  TemplateName getAsTemplate() const {
228    if (Kind != Template)
229      return TemplateName();
230
231    return TemplateName::getFromVoidPointer(
232                                          reinterpret_cast<void*>(TypeOrValue));
233  }
234
235  /// \brief Retrieve the template argument as a template name; if the argument
236  /// is a pack expansion, return the pattern as a template name.
237  TemplateName getAsTemplateOrTemplatePattern() const {
238    if (Kind != Template && Kind != TemplateExpansion)
239      return TemplateName();
240
241    return TemplateName::getFromVoidPointer(
242                                          reinterpret_cast<void*>(TypeOrValue));
243  }
244
245  /// \brief Retrieve the template argument as an integral value.
246  llvm::APSInt *getAsIntegral() {
247    if (Kind != Integral)
248      return 0;
249    return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
250  }
251
252  const llvm::APSInt *getAsIntegral() const {
253    return const_cast<TemplateArgument*>(this)->getAsIntegral();
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, llvm::raw_ostream &Out) const;
314
315  /// \brief Used to insert TemplateArguments into FoldingSets.
316  void Profile(llvm::FoldingSetNodeID &ID, 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      unsigned QualifierRange[2];
327      unsigned TemplateNameLoc;
328      unsigned EllipsisLoc;
329    } Template;
330  };
331
332public:
333  TemplateArgumentLocInfo();
334
335  TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
336
337  TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
338
339  TemplateArgumentLocInfo(SourceRange QualifierRange,
340                          SourceLocation TemplateNameLoc,
341                          SourceLocation EllipsisLoc)
342  {
343    Template.QualifierRange[0] = QualifierRange.getBegin().getRawEncoding();
344    Template.QualifierRange[1] = QualifierRange.getEnd().getRawEncoding();
345    Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
346    Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
347  }
348
349  TypeSourceInfo *getAsTypeSourceInfo() const {
350    return Declarator;
351  }
352
353  Expr *getAsExpr() const {
354    return Expression;
355  }
356
357  SourceRange getTemplateQualifierRange() const {
358    return SourceRange(
359                SourceLocation::getFromRawEncoding(Template.QualifierRange[0]),
360                SourceLocation::getFromRawEncoding(Template.QualifierRange[1]));
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                      SourceRange QualifierRange,
398                      SourceLocation TemplateNameLoc,
399                      SourceLocation EllipsisLoc = SourceLocation())
400    : Argument(Argument),
401      LocInfo(QualifierRange, 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;
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  SourceRange getTemplateQualifierRange() const {
442    assert(Argument.getKind() == TemplateArgument::Template ||
443           Argument.getKind() == TemplateArgument::TemplateExpansion);
444    return LocInfo.getTemplateQualifierRange();
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  TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis,
463                                              ASTContext &Context) const;
464};
465
466/// A convenient class for passing around template argument
467/// information.  Designed to be passed by reference.
468class TemplateArgumentListInfo {
469  llvm::SmallVector<TemplateArgumentLoc, 8> Arguments;
470  SourceLocation LAngleLoc;
471  SourceLocation RAngleLoc;
472
473public:
474  TemplateArgumentListInfo() {}
475
476  TemplateArgumentListInfo(SourceLocation LAngleLoc,
477                           SourceLocation RAngleLoc)
478    : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
479
480  SourceLocation getLAngleLoc() const { return LAngleLoc; }
481  SourceLocation getRAngleLoc() const { return RAngleLoc; }
482
483  void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
484  void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
485
486  unsigned size() const { return Arguments.size(); }
487
488  const TemplateArgumentLoc *getArgumentArray() const {
489    return Arguments.data();
490  }
491
492  const TemplateArgumentLoc &operator[](unsigned I) const {
493    return Arguments[I];
494  }
495
496  void addArgument(const TemplateArgumentLoc &Loc) {
497    Arguments.push_back(Loc);
498  }
499};
500
501const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
502                                    const TemplateArgument &Arg);
503
504inline TemplateSpecializationType::iterator
505    TemplateSpecializationType::end() const {
506  return getArgs() + getNumArgs();
507}
508
509inline DependentTemplateSpecializationType::iterator
510    DependentTemplateSpecializationType::end() const {
511  return getArgs() + getNumArgs();
512}
513
514inline const TemplateArgument &
515    TemplateSpecializationType::getArg(unsigned Idx) const {
516  assert(Idx < getNumArgs() && "Template argument out of range");
517  return getArgs()[Idx];
518}
519
520inline const TemplateArgument &
521    DependentTemplateSpecializationType::getArg(unsigned Idx) const {
522  assert(Idx < getNumArgs() && "Template argument out of range");
523  return getArgs()[Idx];
524}
525
526} // end namespace clang
527
528#endif
529