clang API Documentation

ParsedTemplate.h
Go to the documentation of this file.
00001 //===--- ParsedTemplate.h - Template Parsing Data Types -------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file provides data structures that store the parsed representation of
00011 //  templates.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
00015 #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
00016 
00017 #include "clang/Sema/DeclSpec.h"
00018 #include "clang/Sema/Ownership.h"
00019 #include <cassert>
00020 
00021 namespace clang {  
00022   /// \brief Represents the parsed form of a C++ template argument.
00023   class ParsedTemplateArgument {
00024   public:
00025     /// \brief Describes the kind of template argument that was parsed.
00026     enum KindType {
00027       /// \brief A template type parameter, stored as a type.
00028       Type,
00029       /// \brief A non-type template parameter, stored as an expression.
00030       NonType,
00031       /// \brief A template template argument, stored as a template name.
00032       Template
00033     };
00034 
00035     /// \brief Build an empty template argument. 
00036     ///
00037     /// This template argument is invalid.
00038     ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
00039     
00040     /// \brief Create a template type argument or non-type template argument.
00041     ///
00042     /// \param Arg the template type argument or non-type template argument.
00043     /// \param Loc the location of the type.
00044     ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
00045       : Kind(Kind), Arg(Arg), Loc(Loc) { }
00046     
00047     /// \brief Create a template template argument.
00048     ///
00049     /// \param SS the C++ scope specifier that precedes the template name, if
00050     /// any.
00051     ///
00052     /// \param Template the template to which this template template 
00053     /// argument refers.
00054     ///
00055     /// \param TemplateLoc the location of the template name.
00056     ParsedTemplateArgument(const CXXScopeSpec &SS,
00057                            ParsedTemplateTy Template, 
00058                            SourceLocation TemplateLoc) 
00059       : Kind(ParsedTemplateArgument::Template),
00060         Arg(Template.getAsOpaquePtr()), 
00061         SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
00062     
00063     /// \brief Determine whether the given template argument is invalid.
00064     bool isInvalid() const { return Arg == nullptr; }
00065     
00066     /// \brief Determine what kind of template argument we have.
00067     KindType getKind() const { return Kind; }
00068     
00069     /// \brief Retrieve the template type argument's type.
00070     ParsedType getAsType() const {
00071       assert(Kind == Type && "Not a template type argument");
00072       return ParsedType::getFromOpaquePtr(Arg);
00073     }
00074     
00075     /// \brief Retrieve the non-type template argument's expression.
00076     Expr *getAsExpr() const {
00077       assert(Kind == NonType && "Not a non-type template argument");
00078       return static_cast<Expr*>(Arg);
00079     }
00080     
00081     /// \brief Retrieve the template template argument's template name.
00082     ParsedTemplateTy getAsTemplate() const {
00083       assert(Kind == Template && "Not a template template argument");
00084       return ParsedTemplateTy::getFromOpaquePtr(Arg);
00085     }
00086     
00087     /// \brief Retrieve the location of the template argument.
00088     SourceLocation getLocation() const { return Loc; }
00089     
00090     /// \brief Retrieve the nested-name-specifier that precedes the template
00091     /// name in a template template argument.
00092     const CXXScopeSpec &getScopeSpec() const {
00093       assert(Kind == Template && 
00094              "Only template template arguments can have a scope specifier");
00095       return SS;
00096     }
00097     
00098     /// \brief Retrieve the location of the ellipsis that makes a template
00099     /// template argument into a pack expansion.
00100     SourceLocation getEllipsisLoc() const {
00101       assert(Kind == Template && 
00102              "Only template template arguments can have an ellipsis");
00103       return EllipsisLoc;
00104     }
00105     
00106     /// \brief Retrieve a pack expansion of the given template template
00107     /// argument.
00108     ///
00109     /// \param EllipsisLoc The location of the ellipsis.
00110     ParsedTemplateArgument getTemplatePackExpansion(
00111                                               SourceLocation EllipsisLoc) const;
00112     
00113   private:
00114     KindType Kind;
00115     
00116     /// \brief The actual template argument representation, which may be
00117     /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an
00118     /// expression), or an ActionBase::TemplateTy (for a template).
00119     void *Arg;
00120 
00121     /// \brief The nested-name-specifier that can accompany a template template
00122     /// argument.
00123     CXXScopeSpec SS;
00124 
00125     /// \brief the location of the template argument.
00126     SourceLocation Loc;
00127 
00128     /// \brief The ellipsis location that can accompany a template template
00129     /// argument (turning it into a template template argument expansion).
00130     SourceLocation EllipsisLoc;
00131   };
00132   
00133   /// \brief Information about a template-id annotation
00134   /// token.
00135   ///
00136   /// A template-id annotation token contains the template declaration, 
00137   /// template arguments, whether those template arguments were types, 
00138   /// expressions, or template names, and the source locations for important 
00139   /// tokens. All of the information about template arguments is allocated 
00140   /// directly after this structure.
00141   struct TemplateIdAnnotation {
00142     /// \brief The nested-name-specifier that precedes the template name.
00143     CXXScopeSpec SS;
00144 
00145     /// TemplateKWLoc - The location of the template keyword within the
00146     /// source.
00147     SourceLocation TemplateKWLoc;
00148 
00149     /// TemplateNameLoc - The location of the template name within the
00150     /// source.
00151     SourceLocation TemplateNameLoc;
00152     
00153     /// FIXME: Temporarily stores the name of a specialization
00154     IdentifierInfo *Name;
00155     
00156     /// FIXME: Temporarily stores the overloaded operator kind.
00157     OverloadedOperatorKind Operator;
00158     
00159     /// The declaration of the template corresponding to the
00160     /// template-name.
00161     ParsedTemplateTy Template;
00162     
00163     /// The kind of template that Template refers to.
00164     TemplateNameKind Kind;
00165     
00166     /// The location of the '<' before the template argument
00167     /// list.
00168     SourceLocation LAngleLoc;
00169     
00170     /// The location of the '>' after the template argument
00171     /// list.
00172     SourceLocation RAngleLoc;
00173     
00174     /// NumArgs - The number of template arguments.
00175     unsigned NumArgs;
00176     
00177     /// \brief Retrieves a pointer to the template arguments
00178     ParsedTemplateArgument *getTemplateArgs() { 
00179       return reinterpret_cast<ParsedTemplateArgument *>(this + 1); 
00180     }
00181 
00182     /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
00183     /// appends it to List.
00184     static TemplateIdAnnotation *
00185     Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
00186       TemplateIdAnnotation *TemplateId
00187         = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
00188                                       sizeof(ParsedTemplateArgument) * NumArgs);
00189       TemplateId->NumArgs = NumArgs;
00190       
00191       // Default-construct nested-name-specifier.
00192       new (&TemplateId->SS) CXXScopeSpec();
00193       
00194       // Default-construct parsed template arguments.
00195       ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
00196       for (unsigned I = 0; I != NumArgs; ++I)
00197         new (TemplateArgs + I) ParsedTemplateArgument();
00198       
00199       List.push_back(TemplateId);
00200       return TemplateId;
00201     }
00202     
00203     void Destroy() { 
00204       SS.~CXXScopeSpec();
00205       free(this); 
00206     }
00207   };
00208 
00209   /// Retrieves the range of the given template parameter lists.
00210   SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
00211                                      unsigned NumParams);  
00212 }
00213 
00214 #endif