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