123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- ParsedTemplate.h - Template Parsing Data Types ---------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file provides data structures that store the parsed representation of
- // templates.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
- #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
- #include "clang/Basic/OperatorKinds.h"
- #include "clang/Basic/SourceLocation.h"
- #include "clang/Basic/TemplateKinds.h"
- #include "clang/Sema/DeclSpec.h"
- #include "clang/Sema/Ownership.h"
- #include "llvm/ADT/SmallVector.h"
- #include <cassert>
- #include <cstdlib>
- #include <new>
- namespace clang {
- /// Represents the parsed form of a C++ template argument.
- class ParsedTemplateArgument {
- public:
- /// Describes the kind of template argument that was parsed.
- enum KindType {
- /// A template type parameter, stored as a type.
- Type,
- /// A non-type template parameter, stored as an expression.
- NonType,
- /// A template template argument, stored as a template name.
- Template
- };
- /// Build an empty template argument.
- ///
- /// This template argument is invalid.
- ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
- /// Create a template type argument or non-type template argument.
- ///
- /// \param Arg the template type argument or non-type template argument.
- /// \param Loc the location of the type.
- ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
- : Kind(Kind), Arg(Arg), Loc(Loc) { }
- /// Create a template template argument.
- ///
- /// \param SS the C++ scope specifier that precedes the template name, if
- /// any.
- ///
- /// \param Template the template to which this template template
- /// argument refers.
- ///
- /// \param TemplateLoc the location of the template name.
- ParsedTemplateArgument(const CXXScopeSpec &SS,
- ParsedTemplateTy Template,
- SourceLocation TemplateLoc)
- : Kind(ParsedTemplateArgument::Template),
- Arg(Template.getAsOpaquePtr()), SS(SS), Loc(TemplateLoc) {}
- /// Determine whether the given template argument is invalid.
- bool isInvalid() const { return Arg == nullptr; }
- /// Determine what kind of template argument we have.
- KindType getKind() const { return Kind; }
- /// Retrieve the template type argument's type.
- ParsedType getAsType() const {
- assert(Kind == Type && "Not a template type argument");
- return ParsedType::getFromOpaquePtr(Arg);
- }
- /// Retrieve the non-type template argument's expression.
- Expr *getAsExpr() const {
- assert(Kind == NonType && "Not a non-type template argument");
- return static_cast<Expr*>(Arg);
- }
- /// Retrieve the template template argument's template name.
- ParsedTemplateTy getAsTemplate() const {
- assert(Kind == Template && "Not a template template argument");
- return ParsedTemplateTy::getFromOpaquePtr(Arg);
- }
- /// Retrieve the location of the template argument.
- SourceLocation getLocation() const { return Loc; }
- /// Retrieve the nested-name-specifier that precedes the template
- /// name in a template template argument.
- const CXXScopeSpec &getScopeSpec() const {
- assert(Kind == Template &&
- "Only template template arguments can have a scope specifier");
- return SS;
- }
- /// Retrieve the location of the ellipsis that makes a template
- /// template argument into a pack expansion.
- SourceLocation getEllipsisLoc() const {
- assert(Kind == Template &&
- "Only template template arguments can have an ellipsis");
- return EllipsisLoc;
- }
- /// Retrieve a pack expansion of the given template template
- /// argument.
- ///
- /// \param EllipsisLoc The location of the ellipsis.
- ParsedTemplateArgument getTemplatePackExpansion(
- SourceLocation EllipsisLoc) const;
- private:
- KindType Kind;
- /// The actual template argument representation, which may be
- /// an \c Sema::TypeTy* (for a type), an Expr* (for an
- /// expression), or an Sema::TemplateTy (for a template).
- void *Arg;
- /// The nested-name-specifier that can accompany a template template
- /// argument.
- CXXScopeSpec SS;
- /// the location of the template argument.
- SourceLocation Loc;
- /// The ellipsis location that can accompany a template template
- /// argument (turning it into a template template argument expansion).
- SourceLocation EllipsisLoc;
- };
- /// Information about a template-id annotation
- /// token.
- ///
- /// A template-id annotation token contains the template name,
- /// template arguments, and the source locations for important
- /// tokens. All of the information about template arguments is allocated
- /// directly after this structure.
- /// A template-id annotation token can also be generated by a type-constraint
- /// construct with no explicit template arguments, e.g. "template<C T>" would
- /// annotate C as a TemplateIdAnnotation with no template arguments (the angle
- /// locations would be invalid in this case).
- struct TemplateIdAnnotation final
- : private llvm::TrailingObjects<TemplateIdAnnotation,
- ParsedTemplateArgument> {
- friend TrailingObjects;
- /// TemplateKWLoc - The location of the template keyword.
- /// For e.g. typename T::template Y<U>
- SourceLocation TemplateKWLoc;
- /// TemplateNameLoc - The location of the template name within the
- /// source.
- SourceLocation TemplateNameLoc;
- /// FIXME: Temporarily stores the name of a specialization
- IdentifierInfo *Name;
- /// FIXME: Temporarily stores the overloaded operator kind.
- OverloadedOperatorKind Operator;
- /// The declaration of the template corresponding to the
- /// template-name.
- ParsedTemplateTy Template;
- /// The kind of template that Template refers to. If this is
- /// TNK_Non_template, an error was encountered and diagnosed
- /// when parsing or looking up the template name.
- TemplateNameKind Kind;
- /// The location of the '<' before the template argument
- /// list.
- SourceLocation LAngleLoc;
- /// The location of the '>' after the template argument
- /// list.
- SourceLocation RAngleLoc;
- /// NumArgs - The number of template arguments.
- unsigned NumArgs;
- /// Whether an error was encountered in the template arguments.
- /// If so, NumArgs and the trailing arguments are best-effort.
- bool ArgsInvalid;
- /// Retrieves a pointer to the template arguments
- ParsedTemplateArgument *getTemplateArgs() {
- return getTrailingObjects<ParsedTemplateArgument>();
- }
- /// Creates a new TemplateIdAnnotation with NumArgs arguments and
- /// appends it to List.
- static TemplateIdAnnotation *
- Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc,
- IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
- ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
- SourceLocation LAngleLoc, SourceLocation RAngleLoc,
- ArrayRef<ParsedTemplateArgument> TemplateArgs, bool ArgsInvalid,
- SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
- TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
- totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
- TemplateIdAnnotation(TemplateKWLoc, TemplateNameLoc, Name,
- OperatorKind, OpaqueTemplateName, TemplateKind,
- LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid);
- CleanupList.push_back(TemplateId);
- return TemplateId;
- }
- void Destroy() {
- std::for_each(
- getTemplateArgs(), getTemplateArgs() + NumArgs,
- [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
- this->~TemplateIdAnnotation();
- free(this);
- }
- /// Determine whether this might be a type template.
- bool mightBeType() const {
- return Kind == TNK_Non_template ||
- Kind == TNK_Type_template ||
- Kind == TNK_Dependent_template_name ||
- Kind == TNK_Undeclared_template;
- }
- bool hasInvalidName() const { return Kind == TNK_Non_template; }
- bool hasInvalidArgs() const { return ArgsInvalid; }
- bool isInvalid() const { return hasInvalidName() || hasInvalidArgs(); }
- private:
- TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
- TemplateIdAnnotation(SourceLocation TemplateKWLoc,
- SourceLocation TemplateNameLoc, IdentifierInfo *Name,
- OverloadedOperatorKind OperatorKind,
- ParsedTemplateTy OpaqueTemplateName,
- TemplateNameKind TemplateKind,
- SourceLocation LAngleLoc, SourceLocation RAngleLoc,
- ArrayRef<ParsedTemplateArgument> TemplateArgs,
- bool ArgsInvalid) noexcept
- : TemplateKWLoc(TemplateKWLoc), TemplateNameLoc(TemplateNameLoc),
- Name(Name), Operator(OperatorKind), Template(OpaqueTemplateName),
- Kind(TemplateKind), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
- NumArgs(TemplateArgs.size()), ArgsInvalid(ArgsInvalid) {
- std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
- getTemplateArgs());
- }
- ~TemplateIdAnnotation() = default;
- };
- /// Retrieves the range of the given template parameter lists.
- SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
- unsigned NumParams);
- } // end namespace clang
- #endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|