1 //===--- ParsedTemplate.h - Template Parsing Data Types -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file provides data structures that store the parsed representation of
11 //  templates.
12 //
13 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
15 #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
16 
17 #include "clang/Sema/DeclSpec.h"
18 #include "clang/Sema/Ownership.h"
19 #include <cassert>
20 
21 namespace clang {
22   /// \brief Represents the parsed form of a C++ template argument.
23   class ParsedTemplateArgument {
24   public:
25     /// \brief Describes the kind of template argument that was parsed.
26     enum KindType {
27       /// \brief A template type parameter, stored as a type.
28       Type,
29       /// \brief A non-type template parameter, stored as an expression.
30       NonType,
31       /// \brief A template template argument, stored as a template name.
32       Template
33     };
34 
35     /// \brief Build an empty template argument.
36     ///
37     /// This template argument is invalid.
ParsedTemplateArgument()38     ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
39 
40     /// \brief Create a template type argument or non-type template argument.
41     ///
42     /// \param Arg the template type argument or non-type template argument.
43     /// \param Loc the location of the type.
ParsedTemplateArgument(KindType Kind,void * Arg,SourceLocation Loc)44     ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
45       : Kind(Kind), Arg(Arg), Loc(Loc) { }
46 
47     /// \brief Create a template template argument.
48     ///
49     /// \param SS the C++ scope specifier that precedes the template name, if
50     /// any.
51     ///
52     /// \param Template the template to which this template template
53     /// argument refers.
54     ///
55     /// \param TemplateLoc the location of the template name.
ParsedTemplateArgument(const CXXScopeSpec & SS,ParsedTemplateTy Template,SourceLocation TemplateLoc)56     ParsedTemplateArgument(const CXXScopeSpec &SS,
57                            ParsedTemplateTy Template,
58                            SourceLocation TemplateLoc)
59       : Kind(ParsedTemplateArgument::Template),
60         Arg(Template.getAsOpaquePtr()),
61         SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
62 
63     /// \brief Determine whether the given template argument is invalid.
isInvalid()64     bool isInvalid() const { return Arg == nullptr; }
65 
66     /// \brief Determine what kind of template argument we have.
getKind()67     KindType getKind() const { return Kind; }
68 
69     /// \brief Retrieve the template type argument's type.
getAsType()70     ParsedType getAsType() const {
71       assert(Kind == Type && "Not a template type argument");
72       return ParsedType::getFromOpaquePtr(Arg);
73     }
74 
75     /// \brief Retrieve the non-type template argument's expression.
getAsExpr()76     Expr *getAsExpr() const {
77       assert(Kind == NonType && "Not a non-type template argument");
78       return static_cast<Expr*>(Arg);
79     }
80 
81     /// \brief Retrieve the template template argument's template name.
getAsTemplate()82     ParsedTemplateTy getAsTemplate() const {
83       assert(Kind == Template && "Not a template template argument");
84       return ParsedTemplateTy::getFromOpaquePtr(Arg);
85     }
86 
87     /// \brief Retrieve the location of the template argument.
getLocation()88     SourceLocation getLocation() const { return Loc; }
89 
90     /// \brief Retrieve the nested-name-specifier that precedes the template
91     /// name in a template template argument.
getScopeSpec()92     const CXXScopeSpec &getScopeSpec() const {
93       assert(Kind == Template &&
94              "Only template template arguments can have a scope specifier");
95       return SS;
96     }
97 
98     /// \brief Retrieve the location of the ellipsis that makes a template
99     /// template argument into a pack expansion.
getEllipsisLoc()100     SourceLocation getEllipsisLoc() const {
101       assert(Kind == Template &&
102              "Only template template arguments can have an ellipsis");
103       return EllipsisLoc;
104     }
105 
106     /// \brief Retrieve a pack expansion of the given template template
107     /// argument.
108     ///
109     /// \param EllipsisLoc The location of the ellipsis.
110     ParsedTemplateArgument getTemplatePackExpansion(
111                                               SourceLocation EllipsisLoc) const;
112 
113   private:
114     KindType Kind;
115 
116     /// \brief The actual template argument representation, which may be
117     /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an
118     /// expression), or an ActionBase::TemplateTy (for a template).
119     void *Arg;
120 
121     /// \brief The nested-name-specifier that can accompany a template template
122     /// argument.
123     CXXScopeSpec SS;
124 
125     /// \brief the location of the template argument.
126     SourceLocation Loc;
127 
128     /// \brief The ellipsis location that can accompany a template template
129     /// argument (turning it into a template template argument expansion).
130     SourceLocation EllipsisLoc;
131   };
132 
133   /// \brief Information about a template-id annotation
134   /// token.
135   ///
136   /// A template-id annotation token contains the template declaration,
137   /// template arguments, whether those template arguments were types,
138   /// expressions, or template names, and the source locations for important
139   /// tokens. All of the information about template arguments is allocated
140   /// directly after this structure.
141   struct TemplateIdAnnotation {
142     /// \brief The nested-name-specifier that precedes the template name.
143     CXXScopeSpec SS;
144 
145     /// TemplateKWLoc - The location of the template keyword within the
146     /// source.
147     SourceLocation TemplateKWLoc;
148 
149     /// TemplateNameLoc - The location of the template name within the
150     /// source.
151     SourceLocation TemplateNameLoc;
152 
153     /// FIXME: Temporarily stores the name of a specialization
154     IdentifierInfo *Name;
155 
156     /// FIXME: Temporarily stores the overloaded operator kind.
157     OverloadedOperatorKind Operator;
158 
159     /// The declaration of the template corresponding to the
160     /// template-name.
161     ParsedTemplateTy Template;
162 
163     /// The kind of template that Template refers to.
164     TemplateNameKind Kind;
165 
166     /// The location of the '<' before the template argument
167     /// list.
168     SourceLocation LAngleLoc;
169 
170     /// The location of the '>' after the template argument
171     /// list.
172     SourceLocation RAngleLoc;
173 
174     /// NumArgs - The number of template arguments.
175     unsigned NumArgs;
176 
177     /// \brief Retrieves a pointer to the template arguments
getTemplateArgsTemplateIdAnnotation178     ParsedTemplateArgument *getTemplateArgs() {
179       return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
180     }
181 
182     /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
183     /// appends it to List.
184     static TemplateIdAnnotation *
AllocateTemplateIdAnnotation185     Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
186       TemplateIdAnnotation *TemplateId
187         = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
188                                       sizeof(ParsedTemplateArgument) * NumArgs);
189       TemplateId->NumArgs = NumArgs;
190 
191       // Default-construct nested-name-specifier.
192       new (&TemplateId->SS) CXXScopeSpec();
193 
194       // Default-construct parsed template arguments.
195       ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
196       for (unsigned I = 0; I != NumArgs; ++I)
197         new (TemplateArgs + I) ParsedTemplateArgument();
198 
199       List.push_back(TemplateId);
200       return TemplateId;
201     }
202 
DestroyTemplateIdAnnotation203     void Destroy() {
204       SS.~CXXScopeSpec();
205       free(this);
206     }
207   };
208 
209   /// Retrieves the range of the given template parameter lists.
210   SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
211                                      unsigned NumParams);
212 }
213 
214 #endif
215