1212795Sdim//===--- ParsedTemplate.h - Template Parsing Data Types -------------------===// 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim// 8212795Sdim//===----------------------------------------------------------------------===// 9212795Sdim// 10212795Sdim// This file provides data structures that store the parsed representation of 11212795Sdim// templates. 12212795Sdim// 13212795Sdim//===----------------------------------------------------------------------===// 14212795Sdim#ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H 15212795Sdim#define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H 16212795Sdim 17212795Sdim#include "clang/Sema/DeclSpec.h" 18212795Sdim#include "clang/Sema/Ownership.h" 19212795Sdim#include <cassert> 20212795Sdim 21212795Sdimnamespace clang { 22212795Sdim /// \brief Represents the parsed form of a C++ template argument. 23212795Sdim class ParsedTemplateArgument { 24212795Sdim public: 25212795Sdim /// \brief Describes the kind of template argument that was parsed. 26212795Sdim enum KindType { 27212795Sdim /// \brief A template type parameter, stored as a type. 28212795Sdim Type, 29212795Sdim /// \brief A non-type template parameter, stored as an expression. 30212795Sdim NonType, 31212795Sdim /// \brief A template template argument, stored as a template name. 32212795Sdim Template 33212795Sdim }; 34212795Sdim 35218893Sdim /// \brief Build an empty template argument. 36218893Sdim /// 37218893Sdim /// This template argument is invalid. 38212795Sdim ParsedTemplateArgument() : Kind(Type), Arg(0) { } 39212795Sdim 40212795Sdim /// \brief Create a template type argument or non-type template argument. 41212795Sdim /// 42212795Sdim /// \param Arg the template type argument or non-type template argument. 43212795Sdim /// \param Loc the location of the type. 44212795Sdim ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc) 45212795Sdim : Kind(Kind), Arg(Arg), Loc(Loc) { } 46212795Sdim 47212795Sdim /// \brief Create a template template argument. 48212795Sdim /// 49212795Sdim /// \param SS the C++ scope specifier that precedes the template name, if 50212795Sdim /// any. 51212795Sdim /// 52212795Sdim /// \param Template the template to which this template template 53212795Sdim /// argument refers. 54212795Sdim /// 55212795Sdim /// \param TemplateLoc the location of the template name. 56212795Sdim ParsedTemplateArgument(const CXXScopeSpec &SS, 57212795Sdim ParsedTemplateTy Template, 58212795Sdim SourceLocation TemplateLoc) 59212795Sdim : Kind(ParsedTemplateArgument::Template), 60212795Sdim Arg(Template.getAsOpaquePtr()), 61239462Sdim SS(SS), Loc(TemplateLoc), EllipsisLoc() { } 62212795Sdim 63212795Sdim /// \brief Determine whether the given template argument is invalid. 64212795Sdim bool isInvalid() const { return Arg == 0; } 65212795Sdim 66212795Sdim /// \brief Determine what kind of template argument we have. 67212795Sdim KindType getKind() const { return Kind; } 68212795Sdim 69212795Sdim /// \brief Retrieve the template type argument's type. 70212795Sdim ParsedType getAsType() const { 71212795Sdim assert(Kind == Type && "Not a template type argument"); 72212795Sdim return ParsedType::getFromOpaquePtr(Arg); 73212795Sdim } 74212795Sdim 75212795Sdim /// \brief Retrieve the non-type template argument's expression. 76212795Sdim Expr *getAsExpr() const { 77212795Sdim assert(Kind == NonType && "Not a non-type template argument"); 78212795Sdim return static_cast<Expr*>(Arg); 79212795Sdim } 80212795Sdim 81212795Sdim /// \brief Retrieve the template template argument's template name. 82212795Sdim ParsedTemplateTy getAsTemplate() const { 83212795Sdim assert(Kind == Template && "Not a template template argument"); 84212795Sdim return ParsedTemplateTy::getFromOpaquePtr(Arg); 85212795Sdim } 86212795Sdim 87212795Sdim /// \brief Retrieve the location of the template argument. 88212795Sdim SourceLocation getLocation() const { return Loc; } 89212795Sdim 90212795Sdim /// \brief Retrieve the nested-name-specifier that precedes the template 91212795Sdim /// name in a template template argument. 92212795Sdim const CXXScopeSpec &getScopeSpec() const { 93212795Sdim assert(Kind == Template && 94212795Sdim "Only template template arguments can have a scope specifier"); 95212795Sdim return SS; 96212795Sdim } 97212795Sdim 98218893Sdim /// \brief Retrieve the location of the ellipsis that makes a template 99218893Sdim /// template argument into a pack expansion. 100218893Sdim SourceLocation getEllipsisLoc() const { 101218893Sdim assert(Kind == Template && 102218893Sdim "Only template template arguments can have an ellipsis"); 103218893Sdim return EllipsisLoc; 104218893Sdim } 105218893Sdim 106218893Sdim /// \brief Retrieve a pack expansion of the given template template 107218893Sdim /// argument. 108218893Sdim /// 109218893Sdim /// \param EllipsisLoc The location of the ellipsis. 110218893Sdim ParsedTemplateArgument getTemplatePackExpansion( 111218893Sdim SourceLocation EllipsisLoc) const; 112218893Sdim 113212795Sdim private: 114212795Sdim KindType Kind; 115212795Sdim 116212795Sdim /// \brief The actual template argument representation, which may be 117226633Sdim /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an 118212795Sdim /// expression), or an ActionBase::TemplateTy (for a template). 119212795Sdim void *Arg; 120212795Sdim 121212795Sdim /// \brief The nested-name-specifier that can accompany a template template 122212795Sdim /// argument. 123212795Sdim CXXScopeSpec SS; 124239462Sdim 125239462Sdim /// \brief the location of the template argument. 126239462Sdim SourceLocation Loc; 127239462Sdim 128218893Sdim /// \brief The ellipsis location that can accompany a template template 129218893Sdim /// argument (turning it into a template template argument expansion). 130218893Sdim SourceLocation EllipsisLoc; 131212795Sdim }; 132212795Sdim 133212795Sdim /// \brief Information about a template-id annotation 134212795Sdim /// token. 135212795Sdim /// 136212795Sdim /// A template-id annotation token contains the template declaration, 137212795Sdim /// template arguments, whether those template arguments were types, 138212795Sdim /// expressions, or template names, and the source locations for important 139212795Sdim /// tokens. All of the information about template arguments is allocated 140212795Sdim /// directly after this structure. 141212795Sdim struct TemplateIdAnnotation { 142221345Sdim /// \brief The nested-name-specifier that precedes the template name. 143221345Sdim CXXScopeSpec SS; 144234353Sdim 145234353Sdim /// TemplateKWLoc - The location of the template keyword within the 146234353Sdim /// source. 147234353Sdim SourceLocation TemplateKWLoc; 148234353Sdim 149212795Sdim /// TemplateNameLoc - The location of the template name within the 150212795Sdim /// source. 151212795Sdim SourceLocation TemplateNameLoc; 152212795Sdim 153212795Sdim /// FIXME: Temporarily stores the name of a specialization 154212795Sdim IdentifierInfo *Name; 155212795Sdim 156212795Sdim /// FIXME: Temporarily stores the overloaded operator kind. 157212795Sdim OverloadedOperatorKind Operator; 158212795Sdim 159212795Sdim /// The declaration of the template corresponding to the 160212795Sdim /// template-name. 161212795Sdim ParsedTemplateTy Template; 162212795Sdim 163212795Sdim /// The kind of template that Template refers to. 164212795Sdim TemplateNameKind Kind; 165212795Sdim 166212795Sdim /// The location of the '<' before the template argument 167212795Sdim /// list. 168212795Sdim SourceLocation LAngleLoc; 169212795Sdim 170212795Sdim /// The location of the '>' after the template argument 171212795Sdim /// list. 172212795Sdim SourceLocation RAngleLoc; 173212795Sdim 174212795Sdim /// NumArgs - The number of template arguments. 175212795Sdim unsigned NumArgs; 176212795Sdim 177212795Sdim /// \brief Retrieves a pointer to the template arguments 178212795Sdim ParsedTemplateArgument *getTemplateArgs() { 179212795Sdim return reinterpret_cast<ParsedTemplateArgument *>(this + 1); 180212795Sdim } 181234982Sdim 182234982Sdim /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and 183234982Sdim /// appends it to List. 184234982Sdim static TemplateIdAnnotation * 185234982Sdim Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) { 186212795Sdim TemplateIdAnnotation *TemplateId 187221345Sdim = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) + 188212795Sdim sizeof(ParsedTemplateArgument) * NumArgs); 189212795Sdim TemplateId->NumArgs = NumArgs; 190219077Sdim 191221345Sdim // Default-construct nested-name-specifier. 192221345Sdim new (&TemplateId->SS) CXXScopeSpec(); 193221345Sdim 194219077Sdim // Default-construct parsed template arguments. 195219077Sdim ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs(); 196219077Sdim for (unsigned I = 0; I != NumArgs; ++I) 197219077Sdim new (TemplateArgs + I) ParsedTemplateArgument(); 198219077Sdim 199234982Sdim List.push_back(TemplateId); 200212795Sdim return TemplateId; 201212795Sdim } 202212795Sdim 203221345Sdim void Destroy() { 204221345Sdim SS.~CXXScopeSpec(); 205221345Sdim free(this); 206221345Sdim } 207212795Sdim }; 208218893Sdim 209218893Sdim /// Retrieves the range of the given template parameter lists. 210218893Sdim SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, 211218893Sdim unsigned NumParams); 212212795Sdim} 213212795Sdim 214212795Sdim#endif 215