Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===--- ParsedTemplate.h - Template Parsing Data Types ---------*- 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 data structures that store the parsed representation of
  10. //  templates.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
  15. #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
  16.  
  17. #include "clang/Basic/OperatorKinds.h"
  18. #include "clang/Basic/SourceLocation.h"
  19. #include "clang/Basic/TemplateKinds.h"
  20. #include "clang/Sema/DeclSpec.h"
  21. #include "clang/Sema/Ownership.h"
  22. #include "llvm/ADT/SmallVector.h"
  23. #include <cassert>
  24. #include <cstdlib>
  25. #include <new>
  26.  
  27. namespace clang {
  28.   /// Represents the parsed form of a C++ template argument.
  29.   class ParsedTemplateArgument {
  30.   public:
  31.     /// Describes the kind of template argument that was parsed.
  32.     enum KindType {
  33.       /// A template type parameter, stored as a type.
  34.       Type,
  35.       /// A non-type template parameter, stored as an expression.
  36.       NonType,
  37.       /// A template template argument, stored as a template name.
  38.       Template
  39.     };
  40.  
  41.     /// Build an empty template argument.
  42.     ///
  43.     /// This template argument is invalid.
  44.     ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
  45.  
  46.     /// Create a template type argument or non-type template argument.
  47.     ///
  48.     /// \param Arg the template type argument or non-type template argument.
  49.     /// \param Loc the location of the type.
  50.     ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
  51.       : Kind(Kind), Arg(Arg), Loc(Loc) { }
  52.  
  53.     /// Create a template template argument.
  54.     ///
  55.     /// \param SS the C++ scope specifier that precedes the template name, if
  56.     /// any.
  57.     ///
  58.     /// \param Template the template to which this template template
  59.     /// argument refers.
  60.     ///
  61.     /// \param TemplateLoc the location of the template name.
  62.     ParsedTemplateArgument(const CXXScopeSpec &SS,
  63.                            ParsedTemplateTy Template,
  64.                            SourceLocation TemplateLoc)
  65.       : Kind(ParsedTemplateArgument::Template),
  66.         Arg(Template.getAsOpaquePtr()), SS(SS), Loc(TemplateLoc) {}
  67.  
  68.     /// Determine whether the given template argument is invalid.
  69.     bool isInvalid() const { return Arg == nullptr; }
  70.  
  71.     /// Determine what kind of template argument we have.
  72.     KindType getKind() const { return Kind; }
  73.  
  74.     /// Retrieve the template type argument's type.
  75.     ParsedType getAsType() const {
  76.       assert(Kind == Type && "Not a template type argument");
  77.       return ParsedType::getFromOpaquePtr(Arg);
  78.     }
  79.  
  80.     /// Retrieve the non-type template argument's expression.
  81.     Expr *getAsExpr() const {
  82.       assert(Kind == NonType && "Not a non-type template argument");
  83.       return static_cast<Expr*>(Arg);
  84.     }
  85.  
  86.     /// Retrieve the template template argument's template name.
  87.     ParsedTemplateTy getAsTemplate() const {
  88.       assert(Kind == Template && "Not a template template argument");
  89.       return ParsedTemplateTy::getFromOpaquePtr(Arg);
  90.     }
  91.  
  92.     /// Retrieve the location of the template argument.
  93.     SourceLocation getLocation() const { return Loc; }
  94.  
  95.     /// Retrieve the nested-name-specifier that precedes the template
  96.     /// name in a template template argument.
  97.     const CXXScopeSpec &getScopeSpec() const {
  98.       assert(Kind == Template &&
  99.              "Only template template arguments can have a scope specifier");
  100.       return SS;
  101.     }
  102.  
  103.     /// Retrieve the location of the ellipsis that makes a template
  104.     /// template argument into a pack expansion.
  105.     SourceLocation getEllipsisLoc() const {
  106.       assert(Kind == Template &&
  107.              "Only template template arguments can have an ellipsis");
  108.       return EllipsisLoc;
  109.     }
  110.  
  111.     /// Retrieve a pack expansion of the given template template
  112.     /// argument.
  113.     ///
  114.     /// \param EllipsisLoc The location of the ellipsis.
  115.     ParsedTemplateArgument getTemplatePackExpansion(
  116.                                               SourceLocation EllipsisLoc) const;
  117.  
  118.   private:
  119.     KindType Kind;
  120.  
  121.     /// The actual template argument representation, which may be
  122.     /// an \c Sema::TypeTy* (for a type), an Expr* (for an
  123.     /// expression), or an Sema::TemplateTy (for a template).
  124.     void *Arg;
  125.  
  126.     /// The nested-name-specifier that can accompany a template template
  127.     /// argument.
  128.     CXXScopeSpec SS;
  129.  
  130.     /// the location of the template argument.
  131.     SourceLocation Loc;
  132.  
  133.     /// The ellipsis location that can accompany a template template
  134.     /// argument (turning it into a template template argument expansion).
  135.     SourceLocation EllipsisLoc;
  136.   };
  137.  
  138.   /// Information about a template-id annotation
  139.   /// token.
  140.   ///
  141.   /// A template-id annotation token contains the template name,
  142.   /// template arguments, and the source locations for important
  143.   /// tokens. All of the information about template arguments is allocated
  144.   /// directly after this structure.
  145.   /// A template-id annotation token can also be generated by a type-constraint
  146.   /// construct with no explicit template arguments, e.g. "template<C T>" would
  147.   /// annotate C as a TemplateIdAnnotation with no template arguments (the angle
  148.   /// locations would be invalid in this case).
  149.   struct TemplateIdAnnotation final
  150.       : private llvm::TrailingObjects<TemplateIdAnnotation,
  151.                                       ParsedTemplateArgument> {
  152.     friend TrailingObjects;
  153.     /// TemplateKWLoc - The location of the template keyword.
  154.     /// For e.g. typename T::template Y<U>
  155.     SourceLocation TemplateKWLoc;
  156.  
  157.     /// TemplateNameLoc - The location of the template name within the
  158.     /// source.
  159.     SourceLocation TemplateNameLoc;
  160.  
  161.     /// FIXME: Temporarily stores the name of a specialization
  162.     IdentifierInfo *Name;
  163.  
  164.     /// FIXME: Temporarily stores the overloaded operator kind.
  165.     OverloadedOperatorKind Operator;
  166.  
  167.     /// The declaration of the template corresponding to the
  168.     /// template-name.
  169.     ParsedTemplateTy Template;
  170.  
  171.     /// The kind of template that Template refers to. If this is
  172.     /// TNK_Non_template, an error was encountered and diagnosed
  173.     /// when parsing or looking up the template name.
  174.     TemplateNameKind Kind;
  175.  
  176.     /// The location of the '<' before the template argument
  177.     /// list.
  178.     SourceLocation LAngleLoc;
  179.  
  180.     /// The location of the '>' after the template argument
  181.     /// list.
  182.     SourceLocation RAngleLoc;
  183.  
  184.     /// NumArgs - The number of template arguments.
  185.     unsigned NumArgs;
  186.  
  187.     /// Whether an error was encountered in the template arguments.
  188.     /// If so, NumArgs and the trailing arguments are best-effort.
  189.     bool ArgsInvalid;
  190.  
  191.     /// Retrieves a pointer to the template arguments
  192.     ParsedTemplateArgument *getTemplateArgs() {
  193.       return getTrailingObjects<ParsedTemplateArgument>();
  194.     }
  195.  
  196.     /// Creates a new TemplateIdAnnotation with NumArgs arguments and
  197.     /// appends it to List.
  198.     static TemplateIdAnnotation *
  199.     Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc,
  200.            IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
  201.            ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
  202.            SourceLocation LAngleLoc, SourceLocation RAngleLoc,
  203.            ArrayRef<ParsedTemplateArgument> TemplateArgs, bool ArgsInvalid,
  204.            SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
  205.       TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
  206.           totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
  207.           TemplateIdAnnotation(TemplateKWLoc, TemplateNameLoc, Name,
  208.                                OperatorKind, OpaqueTemplateName, TemplateKind,
  209.                                LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid);
  210.       CleanupList.push_back(TemplateId);
  211.       return TemplateId;
  212.     }
  213.  
  214.     void Destroy() {
  215.       for (ParsedTemplateArgument &A :
  216.            llvm::make_range(getTemplateArgs(), getTemplateArgs() + NumArgs))
  217.         A.~ParsedTemplateArgument();
  218.       this->~TemplateIdAnnotation();
  219.       free(this);
  220.     }
  221.  
  222.     /// Determine whether this might be a type template.
  223.     bool mightBeType() const {
  224.       return Kind == TNK_Non_template ||
  225.              Kind == TNK_Type_template ||
  226.              Kind == TNK_Dependent_template_name ||
  227.              Kind == TNK_Undeclared_template;
  228.     }
  229.  
  230.     bool hasInvalidName() const { return Kind == TNK_Non_template; }
  231.     bool hasInvalidArgs() const { return ArgsInvalid; }
  232.  
  233.     bool isInvalid() const { return hasInvalidName() || hasInvalidArgs(); }
  234.  
  235.   private:
  236.     TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
  237.  
  238.     TemplateIdAnnotation(SourceLocation TemplateKWLoc,
  239.                          SourceLocation TemplateNameLoc, IdentifierInfo *Name,
  240.                          OverloadedOperatorKind OperatorKind,
  241.                          ParsedTemplateTy OpaqueTemplateName,
  242.                          TemplateNameKind TemplateKind,
  243.                          SourceLocation LAngleLoc, SourceLocation RAngleLoc,
  244.                          ArrayRef<ParsedTemplateArgument> TemplateArgs,
  245.                          bool ArgsInvalid) noexcept
  246.         : TemplateKWLoc(TemplateKWLoc), TemplateNameLoc(TemplateNameLoc),
  247.           Name(Name), Operator(OperatorKind), Template(OpaqueTemplateName),
  248.           Kind(TemplateKind), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
  249.           NumArgs(TemplateArgs.size()), ArgsInvalid(ArgsInvalid) {
  250.  
  251.       std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
  252.                               getTemplateArgs());
  253.     }
  254.     ~TemplateIdAnnotation() = default;
  255.   };
  256.  
  257.   /// Retrieves the range of the given template parameter lists.
  258.   SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
  259.                                      unsigned NumParams);
  260. } // end namespace clang
  261.  
  262. #endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
  263.