]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h
Upgrade our copies of clang, llvm, lldb and compiler-rt to r312293 from
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Sema / ParsedTemplate.h
1 //===--- ParsedTemplate.h - Template Parsing Data Types ---------*- C++ -*-===//
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
15 #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
16 #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
17
18 #include "clang/Basic/OperatorKinds.h"
19 #include "clang/Basic/SourceLocation.h"
20 #include "clang/Basic/TemplateKinds.h"
21 #include "clang/Sema/DeclSpec.h"
22 #include "clang/Sema/Ownership.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include <cassert>
25 #include <cstdlib>
26 #include <new>
27
28 namespace clang {  
29   /// \brief Represents the parsed form of a C++ template argument.
30   class ParsedTemplateArgument {
31   public:
32     /// \brief Describes the kind of template argument that was parsed.
33     enum KindType {
34       /// \brief A template type parameter, stored as a type.
35       Type,
36       /// \brief A non-type template parameter, stored as an expression.
37       NonType,
38       /// \brief A template template argument, stored as a template name.
39       Template
40     };
41
42     /// \brief Build an empty template argument. 
43     ///
44     /// This template argument is invalid.
45     ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
46     
47     /// \brief Create a template type argument or non-type template argument.
48     ///
49     /// \param Arg the template type argument or non-type template argument.
50     /// \param Loc the location of the type.
51     ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
52       : Kind(Kind), Arg(Arg), Loc(Loc) { }
53     
54     /// \brief Create a template template argument.
55     ///
56     /// \param SS the C++ scope specifier that precedes the template name, if
57     /// any.
58     ///
59     /// \param Template the template to which this template template 
60     /// argument refers.
61     ///
62     /// \param TemplateLoc the location of the template name.
63     ParsedTemplateArgument(const CXXScopeSpec &SS,
64                            ParsedTemplateTy Template, 
65                            SourceLocation TemplateLoc) 
66       : Kind(ParsedTemplateArgument::Template),
67         Arg(Template.getAsOpaquePtr()), 
68         SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
69     
70     /// \brief Determine whether the given template argument is invalid.
71     bool isInvalid() const { return Arg == nullptr; }
72     
73     /// \brief Determine what kind of template argument we have.
74     KindType getKind() const { return Kind; }
75     
76     /// \brief Retrieve the template type argument's type.
77     ParsedType getAsType() const {
78       assert(Kind == Type && "Not a template type argument");
79       return ParsedType::getFromOpaquePtr(Arg);
80     }
81     
82     /// \brief Retrieve the non-type template argument's expression.
83     Expr *getAsExpr() const {
84       assert(Kind == NonType && "Not a non-type template argument");
85       return static_cast<Expr*>(Arg);
86     }
87     
88     /// \brief Retrieve the template template argument's template name.
89     ParsedTemplateTy getAsTemplate() const {
90       assert(Kind == Template && "Not a template template argument");
91       return ParsedTemplateTy::getFromOpaquePtr(Arg);
92     }
93     
94     /// \brief Retrieve the location of the template argument.
95     SourceLocation getLocation() const { return Loc; }
96     
97     /// \brief Retrieve the nested-name-specifier that precedes the template
98     /// name in a template template argument.
99     const CXXScopeSpec &getScopeSpec() const {
100       assert(Kind == Template && 
101              "Only template template arguments can have a scope specifier");
102       return SS;
103     }
104     
105     /// \brief Retrieve the location of the ellipsis that makes a template
106     /// template argument into a pack expansion.
107     SourceLocation getEllipsisLoc() const {
108       assert(Kind == Template && 
109              "Only template template arguments can have an ellipsis");
110       return EllipsisLoc;
111     }
112     
113     /// \brief Retrieve a pack expansion of the given template template
114     /// argument.
115     ///
116     /// \param EllipsisLoc The location of the ellipsis.
117     ParsedTemplateArgument getTemplatePackExpansion(
118                                               SourceLocation EllipsisLoc) const;
119     
120   private:
121     KindType Kind;
122     
123     /// \brief The actual template argument representation, which may be
124     /// an \c Sema::TypeTy* (for a type), an Expr* (for an
125     /// expression), or an Sema::TemplateTy (for a template).
126     void *Arg;
127
128     /// \brief The nested-name-specifier that can accompany a template template
129     /// argument.
130     CXXScopeSpec SS;
131
132     /// \brief the location of the template argument.
133     SourceLocation Loc;
134
135     /// \brief The ellipsis location that can accompany a template template
136     /// argument (turning it into a template template argument expansion).
137     SourceLocation EllipsisLoc;
138   };
139   
140   /// \brief Information about a template-id annotation
141   /// token.
142   ///
143   /// A template-id annotation token contains the template declaration, 
144   /// template arguments, whether those template arguments were types, 
145   /// expressions, or template names, and the source locations for important 
146   /// tokens. All of the information about template arguments is allocated 
147   /// directly after this structure.
148   struct TemplateIdAnnotation final
149       : private llvm::TrailingObjects<TemplateIdAnnotation,
150                                       ParsedTemplateArgument> {
151     friend TrailingObjects;
152     /// \brief The nested-name-specifier that precedes the template name.
153     CXXScopeSpec SS;
154
155     /// TemplateKWLoc - The location of the template keyword.
156     /// For e.g. typename T::template Y<U>
157     SourceLocation TemplateKWLoc;
158
159     /// TemplateNameLoc - The location of the template name within the
160     /// source.
161     SourceLocation TemplateNameLoc;
162     
163     /// FIXME: Temporarily stores the name of a specialization
164     IdentifierInfo *Name;
165     
166     /// FIXME: Temporarily stores the overloaded operator kind.
167     OverloadedOperatorKind Operator;
168     
169     /// The declaration of the template corresponding to the
170     /// template-name.
171     ParsedTemplateTy Template;
172     
173     /// The kind of template that Template refers to.
174     TemplateNameKind Kind;
175     
176     /// The location of the '<' before the template argument
177     /// list.
178     SourceLocation LAngleLoc;
179     
180     /// The location of the '>' after the template argument
181     /// list.
182     SourceLocation RAngleLoc;
183     
184     /// NumArgs - The number of template arguments.
185     unsigned NumArgs;
186     
187     /// \brief Retrieves a pointer to the template arguments
188     ParsedTemplateArgument *getTemplateArgs() { 
189       return getTrailingObjects<ParsedTemplateArgument>(); 
190     }
191
192     /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
193     /// appends it to List.
194     static TemplateIdAnnotation *
195     Create(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
196            SourceLocation TemplateNameLoc, IdentifierInfo *Name,
197            OverloadedOperatorKind OperatorKind,
198            ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
199            SourceLocation LAngleLoc, SourceLocation RAngleLoc,
200            ArrayRef<ParsedTemplateArgument> TemplateArgs,
201            SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
202
203       TemplateIdAnnotation *TemplateId = new (std::malloc(
204           totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
205           TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
206                                OperatorKind, OpaqueTemplateName, TemplateKind,
207                                LAngleLoc, RAngleLoc, TemplateArgs);
208       CleanupList.push_back(TemplateId);
209       return TemplateId;
210     }
211
212     void Destroy() {
213       std::for_each(
214           getTemplateArgs(), getTemplateArgs() + NumArgs,
215           [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
216       this->~TemplateIdAnnotation();
217       free(this); 
218     }
219   private:
220     TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
221
222     TemplateIdAnnotation(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
223                          SourceLocation TemplateNameLoc, IdentifierInfo *Name,
224                          OverloadedOperatorKind OperatorKind,
225                          ParsedTemplateTy OpaqueTemplateName,
226                          TemplateNameKind TemplateKind,
227                          SourceLocation LAngleLoc, SourceLocation RAngleLoc,
228                          ArrayRef<ParsedTemplateArgument> TemplateArgs) noexcept
229         : SS(SS), TemplateKWLoc(TemplateKWLoc),
230           TemplateNameLoc(TemplateNameLoc), Name(Name), Operator(OperatorKind),
231           Template(OpaqueTemplateName), Kind(TemplateKind),
232           LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
233           NumArgs(TemplateArgs.size()) {
234
235       std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
236                               getTemplateArgs());
237     }
238     ~TemplateIdAnnotation() = default;
239   };
240
241   /// Retrieves the range of the given template parameter lists.
242   SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
243                                      unsigned NumParams);  
244 } // end namespace clang
245
246 #endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H