]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h
Merge clang 7.0.1 and several follow-up changes
[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   /// Represents the parsed form of a C++ template argument.
30   class ParsedTemplateArgument {
31   public:
32     /// Describes the kind of template argument that was parsed.
33     enum KindType {
34       /// A template type parameter, stored as a type.
35       Type,
36       /// A non-type template parameter, stored as an expression.
37       NonType,
38       /// A template template argument, stored as a template name.
39       Template
40     };
41
42     /// Build an empty template argument.
43     ///
44     /// This template argument is invalid.
45     ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
46
47     /// 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     /// 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     /// Determine whether the given template argument is invalid.
71     bool isInvalid() const { return Arg == nullptr; }
72
73     /// Determine what kind of template argument we have.
74     KindType getKind() const { return Kind; }
75
76     /// 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     /// 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     /// 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     /// Retrieve the location of the template argument.
95     SourceLocation getLocation() const { return Loc; }
96
97     /// 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     /// 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     /// 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     /// 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     /// The nested-name-specifier that can accompany a template template
129     /// argument.
130     CXXScopeSpec SS;
131
132     /// the location of the template argument.
133     SourceLocation Loc;
134
135     /// 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   /// 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     /// 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     /// Retrieves a pointer to the template arguments
188     ParsedTemplateArgument *getTemplateArgs() {
189       return getTrailingObjects<ParsedTemplateArgument>();
190     }
191
192     /// 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       TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
203           totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
204           TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
205                                OperatorKind, OpaqueTemplateName, TemplateKind,
206                                LAngleLoc, RAngleLoc, TemplateArgs);
207       CleanupList.push_back(TemplateId);
208       return TemplateId;
209     }
210
211     void Destroy() {
212       std::for_each(
213           getTemplateArgs(), getTemplateArgs() + NumArgs,
214           [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
215       this->~TemplateIdAnnotation();
216       free(this);
217     }
218   private:
219     TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
220
221     TemplateIdAnnotation(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
222                          SourceLocation TemplateNameLoc, IdentifierInfo *Name,
223                          OverloadedOperatorKind OperatorKind,
224                          ParsedTemplateTy OpaqueTemplateName,
225                          TemplateNameKind TemplateKind,
226                          SourceLocation LAngleLoc, SourceLocation RAngleLoc,
227                          ArrayRef<ParsedTemplateArgument> TemplateArgs) noexcept
228         : SS(SS), TemplateKWLoc(TemplateKWLoc),
229           TemplateNameLoc(TemplateNameLoc), Name(Name), Operator(OperatorKind),
230           Template(OpaqueTemplateName), Kind(TemplateKind),
231           LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
232           NumArgs(TemplateArgs.size()) {
233
234       std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
235                               getTemplateArgs());
236     }
237     ~TemplateIdAnnotation() = default;
238   };
239
240   /// Retrieves the range of the given template parameter lists.
241   SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
242                                      unsigned NumParams);
243 } // end namespace clang
244
245 #endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H