Home | History | Annotate | Download | only in AST
      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 
     24 namespace llvm {
     25   class FoldingSetNodeID;
     26 }
     27 
     28 namespace clang {
     29 
     30 class Decl;
     31 class DiagnosticBuilder;
     32 class Expr;
     33 struct PrintingPolicy;
     34 class TypeSourceInfo;
     35 
     36 /// \brief Represents a template argument within a class template
     37 /// specialization.
     38 class TemplateArgument {
     39 public:
     40   /// \brief The kind of template argument we're storing.
     41   enum ArgKind {
     42     /// \brief Represents an empty template argument, e.g., one that has not
     43     /// been deduced.
     44     Null = 0,
     45     /// The template argument is a type. Its value is stored in the
     46     /// TypeOrValue field.
     47     Type,
     48     /// The template argument is a declaration that was provided for a pointer
     49     /// or reference non-type template parameter.
     50     Declaration,
     51     /// The template argument is an integral value stored in an llvm::APSInt
     52     /// that was provided for an integral non-type template parameter.
     53     Integral,
     54     /// The template argument is a template name that was provided for a
     55     /// template template parameter.
     56     Template,
     57     /// The template argument is a pack expansion of a template name that was
     58     /// provided for a template template parameter.
     59     TemplateExpansion,
     60     /// The template argument is a value- or type-dependent expression
     61     /// stored in an Expr*.
     62     Expression,
     63     /// The template argument is actually a parameter pack. Arguments are stored
     64     /// in the Args struct.
     65     Pack
     66   };
     67 
     68 private:
     69   /// \brief The kind of template argument we're storing.
     70   unsigned Kind;
     71 
     72   union {
     73     uintptr_t TypeOrValue;
     74     struct {
     75       char Value[sizeof(llvm::APSInt)];
     76       void *Type;
     77     } Integer;
     78     struct {
     79       const TemplateArgument *Args;
     80       unsigned NumArgs;
     81     } Args;
     82     struct {
     83       void *Name;
     84       unsigned NumExpansions;
     85     } TemplateArg;
     86   };
     87 
     88   TemplateArgument(TemplateName, bool); // DO NOT USE
     89 
     90 public:
     91   /// \brief Construct an empty, invalid template argument.
     92   TemplateArgument() : Kind(Null), TypeOrValue(0) { }
     93 
     94   /// \brief Construct a template type argument.
     95   TemplateArgument(QualType T) : Kind(Type) {
     96     TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
     97   }
     98 
     99   /// \brief Construct a template argument that refers to a
    100   /// declaration, which is either an external declaration or a
    101   /// template declaration.
    102   TemplateArgument(Decl *D) : Kind(Declaration) {
    103     // FIXME: Need to be sure we have the "canonical" 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.
    363 struct TemplateArgumentLocInfo {
    364 private:
    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 
    378 public:
    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.
    419 class TemplateArgumentLoc {
    420   TemplateArgument Argument;
    421   TemplateArgumentLocInfo LocInfo;
    422 
    423 public:
    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;
    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.
    516 class 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 
    525 public:
    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.
    557 struct 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   static std::size_t sizeFor(const TemplateArgumentListInfo &List);
    593 };
    594 
    595 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
    596                                     const TemplateArgument &Arg);
    597 
    598 inline TemplateSpecializationType::iterator
    599     TemplateSpecializationType::end() const {
    600   return getArgs() + getNumArgs();
    601 }
    602 
    603 inline DependentTemplateSpecializationType::iterator
    604     DependentTemplateSpecializationType::end() const {
    605   return getArgs() + getNumArgs();
    606 }
    607 
    608 inline const TemplateArgument &
    609     TemplateSpecializationType::getArg(unsigned Idx) const {
    610   assert(Idx < getNumArgs() && "Template argument out of range");
    611   return getArgs()[Idx];
    612 }
    613 
    614 inline const TemplateArgument &
    615     DependentTemplateSpecializationType::getArg(unsigned Idx) const {
    616   assert(Idx < getNumArgs() && "Template argument out of range");
    617   return getArgs()[Idx];
    618 }
    619 
    620 } // end namespace clang
    621 
    622 #endif
    623