//===--- ParsedTemplate.h - Template Parsing Data Types -------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // 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/Sema/DeclSpec.h" #include "clang/Sema/Ownership.h" #include namespace clang { /// \brief Represents the parsed form of a C++ template argument. class ParsedTemplateArgument { public: /// \brief Describes the kind of template argument that was parsed. enum KindType { /// \brief A template type parameter, stored as a type. Type, /// \brief A non-type template parameter, stored as an expression. NonType, /// \brief A template template argument, stored as a template name. Template }; /// \brief Build an empty template argument. /// /// This template argument is invalid. ParsedTemplateArgument() : Kind(Type), Arg(0) { } /// \brief 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) { } /// \brief 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), EllipsisLoc() { } /// \brief Determine whether the given template argument is invalid. bool isInvalid() const { return Arg == 0; } /// \brief Determine what kind of template argument we have. KindType getKind() const { return Kind; } /// \brief Retrieve the template type argument's type. ParsedType getAsType() const { assert(Kind == Type && "Not a template type argument"); return ParsedType::getFromOpaquePtr(Arg); } /// \brief Retrieve the non-type template argument's expression. Expr *getAsExpr() const { assert(Kind == NonType && "Not a non-type template argument"); return static_cast(Arg); } /// \brief Retrieve the template template argument's template name. ParsedTemplateTy getAsTemplate() const { assert(Kind == Template && "Not a template template argument"); return ParsedTemplateTy::getFromOpaquePtr(Arg); } /// \brief Retrieve the location of the template argument. SourceLocation getLocation() const { return Loc; } /// \brief 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; } /// \brief 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; } /// \brief 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; /// \brief The actual template argument representation, which may be /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an /// expression), or an ActionBase::TemplateTy (for a template). void *Arg; /// \brief The nested-name-specifier that can accompany a template template /// argument. CXXScopeSpec SS; /// \brief the location of the template argument. SourceLocation Loc; /// \brief The ellipsis location that can accompany a template template /// argument (turning it into a template template argument expansion). SourceLocation EllipsisLoc; }; /// \brief Information about a template-id annotation /// token. /// /// A template-id annotation token contains the template declaration, /// template arguments, whether those template arguments were types, /// expressions, or template names, and the source locations for important /// tokens. All of the information about template arguments is allocated /// directly after this structure. struct TemplateIdAnnotation { /// \brief The nested-name-specifier that precedes the template name. CXXScopeSpec SS; /// TemplateKWLoc - The location of the template keyword within the /// source. 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. 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; /// \brief Retrieves a pointer to the template arguments ParsedTemplateArgument *getTemplateArgs() { return reinterpret_cast(this + 1); } /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and /// appends it to List. static TemplateIdAnnotation * Allocate(unsigned NumArgs, SmallVectorImpl &List) { TemplateIdAnnotation *TemplateId = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) + sizeof(ParsedTemplateArgument) * NumArgs); TemplateId->NumArgs = NumArgs; // Default-construct nested-name-specifier. new (&TemplateId->SS) CXXScopeSpec(); // Default-construct parsed template arguments. ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs(); for (unsigned I = 0; I != NumArgs; ++I) new (TemplateArgs + I) ParsedTemplateArgument(); List.push_back(TemplateId); return TemplateId; } void Destroy() { SS.~CXXScopeSpec(); free(this); } }; /// Retrieves the range of the given template parameter lists. SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams); } #endif