Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  This file provides definitions which are common for all kinds of
  10. //  template representation.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
  15. #define LLVM_CLANG_AST_TEMPLATEBASE_H
  16.  
  17. #include "clang/AST/DependenceFlags.h"
  18. #include "clang/AST/NestedNameSpecifier.h"
  19. #include "clang/AST/TemplateName.h"
  20. #include "clang/AST/Type.h"
  21. #include "clang/Basic/LLVM.h"
  22. #include "clang/Basic/SourceLocation.h"
  23. #include "llvm/ADT/APInt.h"
  24. #include "llvm/ADT/APSInt.h"
  25. #include "llvm/ADT/ArrayRef.h"
  26. #include "llvm/ADT/SmallVector.h"
  27. #include "llvm/Support/Compiler.h"
  28. #include "llvm/Support/TrailingObjects.h"
  29. #include <cassert>
  30. #include <cstddef>
  31. #include <cstdint>
  32. #include <optional>
  33.  
  34. namespace llvm {
  35.  
  36. class FoldingSetNodeID;
  37.  
  38. // Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a
  39. // full definition of Expr, but this file only sees a forward del because of
  40. // the dependency.
  41. template <> struct PointerLikeTypeTraits<clang::Expr *> {
  42.   static inline void *getAsVoidPointer(clang::Expr *P) { return P; }
  43.   static inline clang::Expr *getFromVoidPointer(void *P) {
  44.     return static_cast<clang::Expr *>(P);
  45.   }
  46.   static constexpr int NumLowBitsAvailable = 2;
  47. };
  48.  
  49. } // namespace llvm
  50.  
  51. namespace clang {
  52.  
  53. class ASTContext;
  54. class Expr;
  55. struct PrintingPolicy;
  56. class TypeSourceInfo;
  57. class ValueDecl;
  58.  
  59. /// Represents a template argument.
  60. class TemplateArgument {
  61. public:
  62.   /// The kind of template argument we're storing.
  63.   enum ArgKind {
  64.     /// Represents an empty template argument, e.g., one that has not
  65.     /// been deduced.
  66.     Null = 0,
  67.  
  68.     /// The template argument is a type.
  69.     Type,
  70.  
  71.     /// The template argument is a declaration that was provided for a pointer,
  72.     /// reference, or pointer to member non-type template parameter.
  73.     Declaration,
  74.  
  75.     /// The template argument is a null pointer or null pointer to member that
  76.     /// was provided for a non-type template parameter.
  77.     NullPtr,
  78.  
  79.     /// The template argument is an integral value stored in an llvm::APSInt
  80.     /// that was provided for an integral non-type template parameter.
  81.     Integral,
  82.  
  83.     /// The template argument is a template name that was provided for a
  84.     /// template template parameter.
  85.     Template,
  86.  
  87.     /// The template argument is a pack expansion of a template name that was
  88.     /// provided for a template template parameter.
  89.     TemplateExpansion,
  90.  
  91.     /// The template argument is an expression, and we've not resolved it to one
  92.     /// of the other forms yet, either because it's dependent or because we're
  93.     /// representing a non-canonical template argument (for instance, in a
  94.     /// TemplateSpecializationType).
  95.     Expression,
  96.  
  97.     /// The template argument is actually a parameter pack. Arguments are stored
  98.     /// in the Args struct.
  99.     Pack
  100.   };
  101.  
  102. private:
  103.   /// The kind of template argument we're storing.
  104.  
  105.   struct DA {
  106.     unsigned Kind;
  107.     void *QT;
  108.     ValueDecl *D;
  109.   };
  110.   struct I {
  111.     unsigned Kind;
  112.     // We store a decomposed APSInt with the data allocated by ASTContext if
  113.     // BitWidth > 64. The memory may be shared between multiple
  114.     // TemplateArgument instances.
  115.     unsigned BitWidth : 31;
  116.     unsigned IsUnsigned : 1;
  117.     union {
  118.       /// Used to store the <= 64 bits integer value.
  119.       uint64_t VAL;
  120.  
  121.       /// Used to store the >64 bits integer value.
  122.       const uint64_t *pVal;
  123.     };
  124.     void *Type;
  125.   };
  126.   struct A {
  127.     unsigned Kind;
  128.     unsigned NumArgs;
  129.     const TemplateArgument *Args;
  130.   };
  131.   struct TA {
  132.     unsigned Kind;
  133.     unsigned NumExpansions;
  134.     void *Name;
  135.   };
  136.   struct TV {
  137.     unsigned Kind;
  138.     uintptr_t V;
  139.   };
  140.   union {
  141.     struct DA DeclArg;
  142.     struct I Integer;
  143.     struct A Args;
  144.     struct TA TemplateArg;
  145.     struct TV TypeOrValue;
  146.   };
  147.  
  148. public:
  149.   /// Construct an empty, invalid template argument.
  150.   constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
  151.  
  152.   /// Construct a template type argument.
  153.   TemplateArgument(QualType T, bool isNullPtr = false) {
  154.     TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
  155.     TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
  156.   }
  157.  
  158.   /// Construct a template argument that refers to a
  159.   /// declaration, which is either an external declaration or a
  160.   /// template declaration.
  161.   TemplateArgument(ValueDecl *D, QualType QT) {
  162.     assert(D && "Expected decl");
  163.     DeclArg.Kind = Declaration;
  164.     DeclArg.QT = QT.getAsOpaquePtr();
  165.     DeclArg.D = D;
  166.   }
  167.  
  168.   /// Construct an integral constant template argument. The memory to
  169.   /// store the value is allocated with Ctx.
  170.   TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
  171.  
  172.   /// Construct an integral constant template argument with the same
  173.   /// value as Other but a different type.
  174.   TemplateArgument(const TemplateArgument &Other, QualType Type) {
  175.     Integer = Other.Integer;
  176.     Integer.Type = Type.getAsOpaquePtr();
  177.   }
  178.  
  179.   /// Construct a template argument that is a template.
  180.   ///
  181.   /// This form of template argument is generally used for template template
  182.   /// parameters. However, the template name could be a dependent template
  183.   /// name that ends up being instantiated to a function template whose address
  184.   /// is taken.
  185.   ///
  186.   /// \param Name The template name.
  187.   TemplateArgument(TemplateName Name) {
  188.     TemplateArg.Kind = Template;
  189.     TemplateArg.Name = Name.getAsVoidPointer();
  190.     TemplateArg.NumExpansions = 0;
  191.   }
  192.  
  193.   /// Construct a template argument that is a template pack expansion.
  194.   ///
  195.   /// This form of template argument is generally used for template template
  196.   /// parameters. However, the template name could be a dependent template
  197.   /// name that ends up being instantiated to a function template whose address
  198.   /// is taken.
  199.   ///
  200.   /// \param Name The template name.
  201.   ///
  202.   /// \param NumExpansions The number of expansions that will be generated by
  203.   /// instantiating
  204.   TemplateArgument(TemplateName Name, std::optional<unsigned> NumExpansions) {
  205.     TemplateArg.Kind = TemplateExpansion;
  206.     TemplateArg.Name = Name.getAsVoidPointer();
  207.     if (NumExpansions)
  208.       TemplateArg.NumExpansions = *NumExpansions + 1;
  209.     else
  210.       TemplateArg.NumExpansions = 0;
  211.   }
  212.  
  213.   /// Construct a template argument that is an expression.
  214.   ///
  215.   /// This form of template argument only occurs in template argument
  216.   /// lists used for dependent types and for expression; it will not
  217.   /// occur in a non-dependent, canonical template argument list.
  218.   TemplateArgument(Expr *E) {
  219.     TypeOrValue.Kind = Expression;
  220.     TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
  221.   }
  222.  
  223.   /// Construct a template argument that is a template argument pack.
  224.   ///
  225.   /// We assume that storage for the template arguments provided
  226.   /// outlives the TemplateArgument itself.
  227.   explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
  228.     this->Args.Kind = Pack;
  229.     this->Args.Args = Args.data();
  230.     this->Args.NumArgs = Args.size();
  231.   }
  232.  
  233.   TemplateArgument(TemplateName, bool) = delete;
  234.  
  235.   static TemplateArgument getEmptyPack() {
  236.     return TemplateArgument(std::nullopt);
  237.   }
  238.  
  239.   /// Create a new template argument pack by copying the given set of
  240.   /// template arguments.
  241.   static TemplateArgument CreatePackCopy(ASTContext &Context,
  242.                                          ArrayRef<TemplateArgument> Args);
  243.  
  244.   /// Return the kind of stored template argument.
  245.   ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
  246.  
  247.   /// Determine whether this template argument has no value.
  248.   bool isNull() const { return getKind() == Null; }
  249.  
  250.   TemplateArgumentDependence getDependence() const;
  251.  
  252.   /// Whether this template argument is dependent on a template
  253.   /// parameter such that its result can change from one instantiation to
  254.   /// another.
  255.   bool isDependent() const;
  256.  
  257.   /// Whether this template argument is dependent on a template
  258.   /// parameter.
  259.   bool isInstantiationDependent() const;
  260.  
  261.   /// Whether this template argument contains an unexpanded
  262.   /// parameter pack.
  263.   bool containsUnexpandedParameterPack() const;
  264.  
  265.   /// Determine whether this template argument is a pack expansion.
  266.   bool isPackExpansion() const;
  267.  
  268.   /// Retrieve the type for a type template argument.
  269.   QualType getAsType() const {
  270.     assert(getKind() == Type && "Unexpected kind");
  271.     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
  272.   }
  273.  
  274.   /// Retrieve the declaration for a declaration non-type
  275.   /// template argument.
  276.   ValueDecl *getAsDecl() const {
  277.     assert(getKind() == Declaration && "Unexpected kind");
  278.     return DeclArg.D;
  279.   }
  280.  
  281.   QualType getParamTypeForDecl() const {
  282.     assert(getKind() == Declaration && "Unexpected kind");
  283.     return QualType::getFromOpaquePtr(DeclArg.QT);
  284.   }
  285.  
  286.   /// Retrieve the type for null non-type template argument.
  287.   QualType getNullPtrType() const {
  288.     assert(getKind() == NullPtr && "Unexpected kind");
  289.     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
  290.   }
  291.  
  292.   /// Retrieve the template name for a template name argument.
  293.   TemplateName getAsTemplate() const {
  294.     assert(getKind() == Template && "Unexpected kind");
  295.     return TemplateName::getFromVoidPointer(TemplateArg.Name);
  296.   }
  297.  
  298.   /// Retrieve the template argument as a template name; if the argument
  299.   /// is a pack expansion, return the pattern as a template name.
  300.   TemplateName getAsTemplateOrTemplatePattern() const {
  301.     assert((getKind() == Template || getKind() == TemplateExpansion) &&
  302.            "Unexpected kind");
  303.  
  304.     return TemplateName::getFromVoidPointer(TemplateArg.Name);
  305.   }
  306.  
  307.   /// Retrieve the number of expansions that a template template argument
  308.   /// expansion will produce, if known.
  309.   std::optional<unsigned> getNumTemplateExpansions() const;
  310.  
  311.   /// Retrieve the template argument as an integral value.
  312.   // FIXME: Provide a way to read the integral data without copying the value.
  313.   llvm::APSInt getAsIntegral() const {
  314.     assert(getKind() == Integral && "Unexpected kind");
  315.  
  316.     using namespace llvm;
  317.  
  318.     if (Integer.BitWidth <= 64)
  319.       return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
  320.  
  321.     unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
  322.     return APSInt(APInt(Integer.BitWidth, ArrayRef(Integer.pVal, NumWords)),
  323.                   Integer.IsUnsigned);
  324.   }
  325.  
  326.   /// Retrieve the type of the integral value.
  327.   QualType getIntegralType() const {
  328.     assert(getKind() == Integral && "Unexpected kind");
  329.     return QualType::getFromOpaquePtr(Integer.Type);
  330.   }
  331.  
  332.   void setIntegralType(QualType T) {
  333.     assert(getKind() == Integral && "Unexpected kind");
  334.     Integer.Type = T.getAsOpaquePtr();
  335.   }
  336.  
  337.   /// If this is a non-type template argument, get its type. Otherwise,
  338.   /// returns a null QualType.
  339.   QualType getNonTypeTemplateArgumentType() const;
  340.  
  341.   /// Retrieve the template argument as an expression.
  342.   Expr *getAsExpr() const {
  343.     assert(getKind() == Expression && "Unexpected kind");
  344.     return reinterpret_cast<Expr *>(TypeOrValue.V);
  345.   }
  346.  
  347.   /// Iterator that traverses the elements of a template argument pack.
  348.   using pack_iterator = const TemplateArgument *;
  349.  
  350.   /// Iterator referencing the first argument of a template argument
  351.   /// pack.
  352.   pack_iterator pack_begin() const {
  353.     assert(getKind() == Pack);
  354.     return Args.Args;
  355.   }
  356.  
  357.   /// Iterator referencing one past the last argument of a template
  358.   /// argument pack.
  359.   pack_iterator pack_end() const {
  360.     assert(getKind() == Pack);
  361.     return Args.Args + Args.NumArgs;
  362.   }
  363.  
  364.   /// Iterator range referencing all of the elements of a template
  365.   /// argument pack.
  366.   ArrayRef<TemplateArgument> pack_elements() const {
  367.     return llvm::ArrayRef(pack_begin(), pack_end());
  368.   }
  369.  
  370.   /// The number of template arguments in the given template argument
  371.   /// pack.
  372.   unsigned pack_size() const {
  373.     assert(getKind() == Pack);
  374.     return Args.NumArgs;
  375.   }
  376.  
  377.   /// Return the array of arguments in this template argument pack.
  378.   ArrayRef<TemplateArgument> getPackAsArray() const {
  379.     assert(getKind() == Pack);
  380.     return llvm::ArrayRef(Args.Args, Args.NumArgs);
  381.   }
  382.  
  383.   /// Determines whether two template arguments are superficially the
  384.   /// same.
  385.   bool structurallyEquals(const TemplateArgument &Other) const;
  386.  
  387.   /// When the template argument is a pack expansion, returns
  388.   /// the pattern of the pack expansion.
  389.   TemplateArgument getPackExpansionPattern() const;
  390.  
  391.   /// Print this template argument to the given output stream.
  392.   void print(const PrintingPolicy &Policy, raw_ostream &Out,
  393.              bool IncludeType) const;
  394.  
  395.   /// Debugging aid that dumps the template argument.
  396.   void dump(raw_ostream &Out) const;
  397.  
  398.   /// Debugging aid that dumps the template argument to standard error.
  399.   void dump() const;
  400.  
  401.   /// Used to insert TemplateArguments into FoldingSets.
  402.   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
  403. };
  404.  
  405. /// Location information for a TemplateArgument.
  406. struct TemplateArgumentLocInfo {
  407. private:
  408.   struct TemplateTemplateArgLocInfo {
  409.     // FIXME: We'd like to just use the qualifier in the TemplateName,
  410.     // but template arguments get canonicalized too quickly.
  411.     NestedNameSpecifier *Qualifier;
  412.     void *QualifierLocData;
  413.     SourceLocation TemplateNameLoc;
  414.     SourceLocation EllipsisLoc;
  415.   };
  416.  
  417.   llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
  418.       Pointer;
  419.  
  420.   TemplateTemplateArgLocInfo *getTemplate() const {
  421.     return Pointer.get<TemplateTemplateArgLocInfo *>();
  422.   }
  423.  
  424. public:
  425.   TemplateArgumentLocInfo() {}
  426.   TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
  427.  
  428.   TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
  429.   // Ctx is used for allocation -- this case is unusually large and also rare,
  430.   // so we store the payload out-of-line.
  431.   TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
  432.                           SourceLocation TemplateNameLoc,
  433.                           SourceLocation EllipsisLoc);
  434.  
  435.   TypeSourceInfo *getAsTypeSourceInfo() const {
  436.     return Pointer.get<TypeSourceInfo *>();
  437.   }
  438.  
  439.   Expr *getAsExpr() const { return Pointer.get<Expr *>(); }
  440.  
  441.   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
  442.     const auto *Template = getTemplate();
  443.     return NestedNameSpecifierLoc(Template->Qualifier,
  444.                                   Template->QualifierLocData);
  445.   }
  446.  
  447.   SourceLocation getTemplateNameLoc() const {
  448.     return getTemplate()->TemplateNameLoc;
  449.   }
  450.  
  451.   SourceLocation getTemplateEllipsisLoc() const {
  452.     return getTemplate()->EllipsisLoc;
  453.   }
  454. };
  455.  
  456. /// Location wrapper for a TemplateArgument.  TemplateArgument is to
  457. /// TemplateArgumentLoc as Type is to TypeLoc.
  458. class TemplateArgumentLoc {
  459.   TemplateArgument Argument;
  460.   TemplateArgumentLocInfo LocInfo;
  461.  
  462. public:
  463.   TemplateArgumentLoc() {}
  464.  
  465.   TemplateArgumentLoc(const TemplateArgument &Argument,
  466.                       TemplateArgumentLocInfo Opaque)
  467.       : Argument(Argument), LocInfo(Opaque) {}
  468.  
  469.   TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
  470.       : Argument(Argument), LocInfo(TInfo) {
  471.     assert(Argument.getKind() == TemplateArgument::Type);
  472.   }
  473.  
  474.   TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
  475.       : Argument(Argument), LocInfo(E) {
  476.  
  477.     // Permit any kind of template argument that can be represented with an
  478.     // expression.
  479.     assert(Argument.getKind() == TemplateArgument::NullPtr ||
  480.            Argument.getKind() == TemplateArgument::Integral ||
  481.            Argument.getKind() == TemplateArgument::Declaration ||
  482.            Argument.getKind() == TemplateArgument::Expression);
  483.   }
  484.  
  485.   TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
  486.                       NestedNameSpecifierLoc QualifierLoc,
  487.                       SourceLocation TemplateNameLoc,
  488.                       SourceLocation EllipsisLoc = SourceLocation())
  489.       : Argument(Argument),
  490.         LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
  491.     assert(Argument.getKind() == TemplateArgument::Template ||
  492.            Argument.getKind() == TemplateArgument::TemplateExpansion);
  493.   }
  494.  
  495.   /// - Fetches the primary location of the argument.
  496.   SourceLocation getLocation() const {
  497.     if (Argument.getKind() == TemplateArgument::Template ||
  498.         Argument.getKind() == TemplateArgument::TemplateExpansion)
  499.       return getTemplateNameLoc();
  500.  
  501.     return getSourceRange().getBegin();
  502.   }
  503.  
  504.   /// - Fetches the full source range of the argument.
  505.   SourceRange getSourceRange() const LLVM_READONLY;
  506.  
  507.   const TemplateArgument &getArgument() const {
  508.     return Argument;
  509.   }
  510.  
  511.   TemplateArgumentLocInfo getLocInfo() const {
  512.     return LocInfo;
  513.   }
  514.  
  515.   TypeSourceInfo *getTypeSourceInfo() const {
  516.     if (Argument.getKind() != TemplateArgument::Type)
  517.       return nullptr;
  518.     return LocInfo.getAsTypeSourceInfo();
  519.   }
  520.  
  521.   Expr *getSourceExpression() const {
  522.     assert(Argument.getKind() == TemplateArgument::Expression);
  523.     return LocInfo.getAsExpr();
  524.   }
  525.  
  526.   Expr *getSourceDeclExpression() const {
  527.     assert(Argument.getKind() == TemplateArgument::Declaration);
  528.     return LocInfo.getAsExpr();
  529.   }
  530.  
  531.   Expr *getSourceNullPtrExpression() const {
  532.     assert(Argument.getKind() == TemplateArgument::NullPtr);
  533.     return LocInfo.getAsExpr();
  534.   }
  535.  
  536.   Expr *getSourceIntegralExpression() const {
  537.     assert(Argument.getKind() == TemplateArgument::Integral);
  538.     return LocInfo.getAsExpr();
  539.   }
  540.  
  541.   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
  542.     if (Argument.getKind() != TemplateArgument::Template &&
  543.         Argument.getKind() != TemplateArgument::TemplateExpansion)
  544.       return NestedNameSpecifierLoc();
  545.     return LocInfo.getTemplateQualifierLoc();
  546.   }
  547.  
  548.   SourceLocation getTemplateNameLoc() const {
  549.     if (Argument.getKind() != TemplateArgument::Template &&
  550.         Argument.getKind() != TemplateArgument::TemplateExpansion)
  551.       return SourceLocation();
  552.     return LocInfo.getTemplateNameLoc();
  553.   }
  554.  
  555.   SourceLocation getTemplateEllipsisLoc() const {
  556.     if (Argument.getKind() != TemplateArgument::TemplateExpansion)
  557.       return SourceLocation();
  558.     return LocInfo.getTemplateEllipsisLoc();
  559.   }
  560. };
  561.  
  562. /// A convenient class for passing around template argument
  563. /// information.  Designed to be passed by reference.
  564. class TemplateArgumentListInfo {
  565.   SmallVector<TemplateArgumentLoc, 8> Arguments;
  566.   SourceLocation LAngleLoc;
  567.   SourceLocation RAngleLoc;
  568.  
  569. public:
  570.   TemplateArgumentListInfo() = default;
  571.  
  572.   TemplateArgumentListInfo(SourceLocation LAngleLoc,
  573.                            SourceLocation RAngleLoc)
  574.       : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
  575.  
  576.   // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
  577.   // instead.
  578.   void *operator new(size_t bytes, ASTContext &C) = delete;
  579.  
  580.   SourceLocation getLAngleLoc() const { return LAngleLoc; }
  581.   SourceLocation getRAngleLoc() const { return RAngleLoc; }
  582.  
  583.   void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
  584.   void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
  585.  
  586.   unsigned size() const { return Arguments.size(); }
  587.  
  588.   const TemplateArgumentLoc *getArgumentArray() const {
  589.     return Arguments.data();
  590.   }
  591.  
  592.   llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
  593.     return Arguments;
  594.   }
  595.  
  596.   const TemplateArgumentLoc &operator[](unsigned I) const {
  597.     return Arguments[I];
  598.   }
  599.  
  600.   TemplateArgumentLoc &operator[](unsigned I) {
  601.     return Arguments[I];
  602.   }
  603.  
  604.   void addArgument(const TemplateArgumentLoc &Loc) {
  605.     Arguments.push_back(Loc);
  606.   }
  607. };
  608.  
  609. /// Represents an explicit template argument list in C++, e.g.,
  610. /// the "<int>" in "sort<int>".
  611. /// This is safe to be used inside an AST node, in contrast with
  612. /// TemplateArgumentListInfo.
  613. struct ASTTemplateArgumentListInfo final
  614.     : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
  615.                                     TemplateArgumentLoc> {
  616. private:
  617.   friend class ASTNodeImporter;
  618.   friend TrailingObjects;
  619.  
  620.   ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
  621.  
  622.   // FIXME: Is it ever necessary to copy to another context?
  623.   ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List);
  624.  
  625. public:
  626.   /// The source location of the left angle bracket ('<').
  627.   SourceLocation LAngleLoc;
  628.  
  629.   /// The source location of the right angle bracket ('>').
  630.   SourceLocation RAngleLoc;
  631.  
  632.   /// The number of template arguments in TemplateArgs.
  633.   unsigned NumTemplateArgs;
  634.  
  635.   SourceLocation getLAngleLoc() const { return LAngleLoc; }
  636.   SourceLocation getRAngleLoc() const { return RAngleLoc; }
  637.  
  638.   /// Retrieve the template arguments
  639.   const TemplateArgumentLoc *getTemplateArgs() const {
  640.     return getTrailingObjects<TemplateArgumentLoc>();
  641.   }
  642.   unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
  643.  
  644.   llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
  645.     return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs());
  646.   }
  647.  
  648.   const TemplateArgumentLoc &operator[](unsigned I) const {
  649.     return getTemplateArgs()[I];
  650.   }
  651.  
  652.   static const ASTTemplateArgumentListInfo *
  653.   Create(const ASTContext &C, const TemplateArgumentListInfo &List);
  654.  
  655.   // FIXME: Is it ever necessary to copy to another context?
  656.   static const ASTTemplateArgumentListInfo *
  657.   Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List);
  658. };
  659.  
  660. /// Represents an explicit template argument list in C++, e.g.,
  661. /// the "<int>" in "sort<int>".
  662. ///
  663. /// It is intended to be used as a trailing object on AST nodes, and
  664. /// as such, doesn't contain the array of TemplateArgumentLoc itself,
  665. /// but expects the containing object to also provide storage for
  666. /// that.
  667. struct alignas(void *) ASTTemplateKWAndArgsInfo {
  668.   /// The source location of the left angle bracket ('<').
  669.   SourceLocation LAngleLoc;
  670.  
  671.   /// The source location of the right angle bracket ('>').
  672.   SourceLocation RAngleLoc;
  673.  
  674.   /// The source location of the template keyword; this is used
  675.   /// as part of the representation of qualified identifiers, such as
  676.   /// S<T>::template apply<T>.  Will be empty if this expression does
  677.   /// not have a template keyword.
  678.   SourceLocation TemplateKWLoc;
  679.  
  680.   /// The number of template arguments in TemplateArgs.
  681.   unsigned NumTemplateArgs;
  682.  
  683.   void initializeFrom(SourceLocation TemplateKWLoc,
  684.                       const TemplateArgumentListInfo &List,
  685.                       TemplateArgumentLoc *OutArgArray);
  686.   // FIXME: The parameter Deps is the result populated by this method, the
  687.   // caller doesn't need it since it is populated by computeDependence. remove
  688.   // it.
  689.   void initializeFrom(SourceLocation TemplateKWLoc,
  690.                       const TemplateArgumentListInfo &List,
  691.                       TemplateArgumentLoc *OutArgArray,
  692.                       TemplateArgumentDependence &Deps);
  693.   void initializeFrom(SourceLocation TemplateKWLoc);
  694.  
  695.   void copyInto(const TemplateArgumentLoc *ArgArray,
  696.                 TemplateArgumentListInfo &List) const;
  697. };
  698.  
  699. const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
  700.                                       const TemplateArgument &Arg);
  701.  
  702. } // namespace clang
  703.  
  704. #endif // LLVM_CLANG_AST_TEMPLATEBASE_H
  705.