diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/Parse/Template.h')
-rw-r--r-- | contrib/llvm/tools/clang/include/clang/Parse/Template.h | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Template.h b/contrib/llvm/tools/clang/include/clang/Parse/Template.h new file mode 100644 index 0000000..1f8ccfb --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Parse/Template.h @@ -0,0 +1,183 @@ +//===--- Template.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_PARSE_TEMPLATE_H +#define LLVM_CLANG_PARSE_TEMPLATE_H + +#include "clang/Parse/DeclSpec.h" +#include "clang/Parse/Ownership.h" +#include <cassert> + +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 + 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, + ActionBase::TemplateTy Template, + SourceLocation TemplateLoc) + : Kind(ParsedTemplateArgument::Template), Arg(Template.get()), + Loc(TemplateLoc), SS(SS) { } + + /// \brief Determine whether the given template argument is invalid. + bool isInvalid() { 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. + ActionBase::TypeTy *getAsType() const { + assert(Kind == Type && "Not a template type argument"); + return Arg; + } + + /// \brief Retrieve the non-type template argument's expression. + ActionBase::ExprTy *getAsExpr() const { + assert(Kind == NonType && "Not a non-type template argument"); + return Arg; + } + + /// \brief Retrieve the template template argument's template name. + ActionBase::TemplateTy getAsTemplate() const { + assert(Kind == Template && "Not a template template argument"); + return ActionBase::TemplateTy::make(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; + } + + private: + KindType Kind; + + /// \brief The actual template argument representation, which may be + /// an \c ActionBase::TypeTy* (for a type), an ActionBase::ExprTy* (for an + /// expression), or an ActionBase::TemplateTy (for a template). + void *Arg; + + /// \brief the location of the template argument. + SourceLocation Loc; + + /// \brief The nested-name-specifier that can accompany a template template + /// argument. + CXXScopeSpec SS; + }; + + /// \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 { + /// 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. This is an Action::TemplateTy. + void *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<ParsedTemplateArgument *>(this + 1); + } + + static TemplateIdAnnotation* Allocate(unsigned NumArgs) { + TemplateIdAnnotation *TemplateId + = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) + + sizeof(ParsedTemplateArgument) * NumArgs); + TemplateId->NumArgs = NumArgs; + return TemplateId; + } + + void Destroy() { free(this); } + }; + +#if !defined(DISABLE_SMART_POINTERS) + inline void ASTTemplateArgsPtr::destroy() { + if (!Count) + return; + + for (unsigned I = 0; I != Count; ++I) + if (Args[I].getKind() == ParsedTemplateArgument::NonType) + Actions.DeleteExpr(Args[I].getAsExpr()); + + Count = 0; + } +#endif + + inline const ParsedTemplateArgument & + ASTTemplateArgsPtr::operator[](unsigned Arg) const { + return Args[Arg]; + } +} + +#endif |