Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- TemplateName.h - C++ Template Name Representation --------*- 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 defines the TemplateName interface and subclasses. |
||
10 | // |
||
11 | //===----------------------------------------------------------------------===// |
||
12 | |||
13 | #ifndef LLVM_CLANG_AST_TEMPLATENAME_H |
||
14 | #define LLVM_CLANG_AST_TEMPLATENAME_H |
||
15 | |||
16 | #include "clang/AST/DependenceFlags.h" |
||
17 | #include "clang/AST/NestedNameSpecifier.h" |
||
18 | #include "clang/Basic/LLVM.h" |
||
19 | #include "llvm/ADT/FoldingSet.h" |
||
20 | #include "llvm/ADT/PointerIntPair.h" |
||
21 | #include "llvm/ADT/PointerUnion.h" |
||
22 | #include "llvm/Support/PointerLikeTypeTraits.h" |
||
23 | #include <cassert> |
||
24 | #include <optional> |
||
25 | |||
26 | namespace clang { |
||
27 | |||
28 | class ASTContext; |
||
29 | class Decl; |
||
30 | class DependentTemplateName; |
||
31 | class IdentifierInfo; |
||
32 | class NamedDecl; |
||
33 | class NestedNameSpecifier; |
||
34 | enum OverloadedOperatorKind : int; |
||
35 | class OverloadedTemplateStorage; |
||
36 | class AssumedTemplateStorage; |
||
37 | struct PrintingPolicy; |
||
38 | class QualifiedTemplateName; |
||
39 | class SubstTemplateTemplateParmPackStorage; |
||
40 | class SubstTemplateTemplateParmStorage; |
||
41 | class TemplateArgument; |
||
42 | class TemplateDecl; |
||
43 | class TemplateTemplateParmDecl; |
||
44 | class UsingShadowDecl; |
||
45 | |||
46 | /// Implementation class used to describe either a set of overloaded |
||
47 | /// template names or an already-substituted template template parameter pack. |
||
48 | class UncommonTemplateNameStorage { |
||
49 | protected: |
||
50 | enum Kind { |
||
51 | Overloaded, |
||
52 | Assumed, // defined in DeclarationName.h |
||
53 | SubstTemplateTemplateParm, |
||
54 | SubstTemplateTemplateParmPack |
||
55 | }; |
||
56 | |||
57 | struct BitsTag { |
||
58 | /// A Kind. |
||
59 | unsigned Kind : 2; |
||
60 | |||
61 | // The template parameter index. |
||
62 | unsigned Index : 15; |
||
63 | |||
64 | /// The pack index, or the number of stored templates |
||
65 | /// or template arguments, depending on which subclass we have. |
||
66 | unsigned Data : 15; |
||
67 | }; |
||
68 | |||
69 | union { |
||
70 | struct BitsTag Bits; |
||
71 | void *PointerAlignment; |
||
72 | }; |
||
73 | |||
74 | UncommonTemplateNameStorage(Kind Kind, unsigned Index, unsigned Data) { |
||
75 | Bits.Kind = Kind; |
||
76 | Bits.Index = Index; |
||
77 | Bits.Data = Data; |
||
78 | } |
||
79 | |||
80 | public: |
||
81 | OverloadedTemplateStorage *getAsOverloadedStorage() { |
||
82 | return Bits.Kind == Overloaded |
||
83 | ? reinterpret_cast<OverloadedTemplateStorage *>(this) |
||
84 | : nullptr; |
||
85 | } |
||
86 | |||
87 | AssumedTemplateStorage *getAsAssumedTemplateName() { |
||
88 | return Bits.Kind == Assumed |
||
89 | ? reinterpret_cast<AssumedTemplateStorage *>(this) |
||
90 | : nullptr; |
||
91 | } |
||
92 | |||
93 | SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() { |
||
94 | return Bits.Kind == SubstTemplateTemplateParm |
||
95 | ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this) |
||
96 | : nullptr; |
||
97 | } |
||
98 | |||
99 | SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() { |
||
100 | return Bits.Kind == SubstTemplateTemplateParmPack |
||
101 | ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this) |
||
102 | : nullptr; |
||
103 | } |
||
104 | }; |
||
105 | |||
106 | /// A structure for storing the information associated with an |
||
107 | /// overloaded template name. |
||
108 | class OverloadedTemplateStorage : public UncommonTemplateNameStorage { |
||
109 | friend class ASTContext; |
||
110 | |||
111 | OverloadedTemplateStorage(unsigned size) |
||
112 | : UncommonTemplateNameStorage(Overloaded, 0, size) {} |
||
113 | |||
114 | NamedDecl **getStorage() { |
||
115 | return reinterpret_cast<NamedDecl **>(this + 1); |
||
116 | } |
||
117 | NamedDecl * const *getStorage() const { |
||
118 | return reinterpret_cast<NamedDecl *const *>(this + 1); |
||
119 | } |
||
120 | |||
121 | public: |
||
122 | unsigned size() const { return Bits.Data; } |
||
123 | |||
124 | using iterator = NamedDecl *const *; |
||
125 | |||
126 | iterator begin() const { return getStorage(); } |
||
127 | iterator end() const { return getStorage() + Bits.Data; } |
||
128 | |||
129 | llvm::ArrayRef<NamedDecl*> decls() const { |
||
130 | return llvm::ArrayRef(begin(), end()); |
||
131 | } |
||
132 | }; |
||
133 | |||
134 | /// A structure for storing an already-substituted template template |
||
135 | /// parameter pack. |
||
136 | /// |
||
137 | /// This kind of template names occurs when the parameter pack has been |
||
138 | /// provided with a template template argument pack in a context where its |
||
139 | /// enclosing pack expansion could not be fully expanded. |
||
140 | class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage, |
||
141 | public llvm::FoldingSetNode { |
||
142 | const TemplateArgument *Arguments; |
||
143 | llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal; |
||
144 | |||
145 | public: |
||
146 | SubstTemplateTemplateParmPackStorage(ArrayRef<TemplateArgument> ArgPack, |
||
147 | Decl *AssociatedDecl, unsigned Index, |
||
148 | bool Final); |
||
149 | |||
150 | /// A template-like entity which owns the whole pattern being substituted. |
||
151 | /// This will own a set of template parameters. |
||
152 | Decl *getAssociatedDecl() const; |
||
153 | |||
154 | /// Returns the index of the replaced parameter in the associated declaration. |
||
155 | /// This should match the result of `getParameterPack()->getIndex()`. |
||
156 | unsigned getIndex() const { return Bits.Index; } |
||
157 | |||
158 | // When true the substitution will be 'Final' (subst node won't be placed). |
||
159 | bool getFinal() const; |
||
160 | |||
161 | /// Retrieve the template template parameter pack being substituted. |
||
162 | TemplateTemplateParmDecl *getParameterPack() const; |
||
163 | |||
164 | /// Retrieve the template template argument pack with which this |
||
165 | /// parameter was substituted. |
||
166 | TemplateArgument getArgumentPack() const; |
||
167 | |||
168 | void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context); |
||
169 | |||
170 | static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context, |
||
171 | const TemplateArgument &ArgPack, Decl *AssociatedDecl, |
||
172 | unsigned Index, bool Final); |
||
173 | }; |
||
174 | |||
175 | /// Represents a C++ template name within the type system. |
||
176 | /// |
||
177 | /// A C++ template name refers to a template within the C++ type |
||
178 | /// system. In most cases, a template name is simply a reference to a |
||
179 | /// class template, e.g. |
||
180 | /// |
||
181 | /// \code |
||
182 | /// template<typename T> class X { }; |
||
183 | /// |
||
184 | /// X<int> xi; |
||
185 | /// \endcode |
||
186 | /// |
||
187 | /// Here, the 'X' in \c X<int> is a template name that refers to the |
||
188 | /// declaration of the class template X, above. Template names can |
||
189 | /// also refer to function templates, C++0x template aliases, etc. |
||
190 | /// |
||
191 | /// Some template names are dependent. For example, consider: |
||
192 | /// |
||
193 | /// \code |
||
194 | /// template<typename MetaFun, typename T1, typename T2> struct apply2 { |
||
195 | /// typedef typename MetaFun::template apply<T1, T2>::type type; |
||
196 | /// }; |
||
197 | /// \endcode |
||
198 | /// |
||
199 | /// Here, "apply" is treated as a template name within the typename |
||
200 | /// specifier in the typedef. "apply" is a nested template, and can |
||
201 | /// only be understood in the context of |
||
202 | class TemplateName { |
||
203 | // NameDecl is either a TemplateDecl or a UsingShadowDecl depending on the |
||
204 | // NameKind. |
||
205 | // !! There is no free low bits in 32-bit builds to discriminate more than 4 |
||
206 | // pointer types in PointerUnion. |
||
207 | using StorageType = |
||
208 | llvm::PointerUnion<Decl *, UncommonTemplateNameStorage *, |
||
209 | QualifiedTemplateName *, DependentTemplateName *>; |
||
210 | |||
211 | StorageType Storage; |
||
212 | |||
213 | explicit TemplateName(void *Ptr); |
||
214 | |||
215 | public: |
||
216 | // Kind of name that is actually stored. |
||
217 | enum NameKind { |
||
218 | /// A single template declaration. |
||
219 | Template, |
||
220 | |||
221 | /// A set of overloaded template declarations. |
||
222 | OverloadedTemplate, |
||
223 | |||
224 | /// An unqualified-id that has been assumed to name a function template |
||
225 | /// that will be found by ADL. |
||
226 | AssumedTemplate, |
||
227 | |||
228 | /// A qualified template name, where the qualification is kept |
||
229 | /// to describe the source code as written. |
||
230 | QualifiedTemplate, |
||
231 | |||
232 | /// A dependent template name that has not been resolved to a |
||
233 | /// template (or set of templates). |
||
234 | DependentTemplate, |
||
235 | |||
236 | /// A template template parameter that has been substituted |
||
237 | /// for some other template name. |
||
238 | SubstTemplateTemplateParm, |
||
239 | |||
240 | /// A template template parameter pack that has been substituted for |
||
241 | /// a template template argument pack, but has not yet been expanded into |
||
242 | /// individual arguments. |
||
243 | SubstTemplateTemplateParmPack, |
||
244 | |||
245 | /// A template name that refers to a template declaration found through a |
||
246 | /// specific using shadow declaration. |
||
247 | UsingTemplate, |
||
248 | }; |
||
249 | |||
250 | TemplateName() = default; |
||
251 | explicit TemplateName(TemplateDecl *Template); |
||
252 | explicit TemplateName(OverloadedTemplateStorage *Storage); |
||
253 | explicit TemplateName(AssumedTemplateStorage *Storage); |
||
254 | explicit TemplateName(SubstTemplateTemplateParmStorage *Storage); |
||
255 | explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage); |
||
256 | explicit TemplateName(QualifiedTemplateName *Qual); |
||
257 | explicit TemplateName(DependentTemplateName *Dep); |
||
258 | explicit TemplateName(UsingShadowDecl *Using); |
||
259 | |||
260 | /// Determine whether this template name is NULL. |
||
261 | bool isNull() const; |
||
262 | |||
263 | // Get the kind of name that is actually stored. |
||
264 | NameKind getKind() const; |
||
265 | |||
266 | /// Retrieve the underlying template declaration that |
||
267 | /// this template name refers to, if known. |
||
268 | /// |
||
269 | /// \returns The template declaration that this template name refers |
||
270 | /// to, if any. If the template name does not refer to a specific |
||
271 | /// declaration because it is a dependent name, or if it refers to a |
||
272 | /// set of function templates, returns NULL. |
||
273 | TemplateDecl *getAsTemplateDecl() const; |
||
274 | |||
275 | /// Retrieve the underlying, overloaded function template |
||
276 | /// declarations that this template name refers to, if known. |
||
277 | /// |
||
278 | /// \returns The set of overloaded function templates that this template |
||
279 | /// name refers to, if known. If the template name does not refer to a |
||
280 | /// specific set of function templates because it is a dependent name or |
||
281 | /// refers to a single template, returns NULL. |
||
282 | OverloadedTemplateStorage *getAsOverloadedTemplate() const; |
||
283 | |||
284 | /// Retrieve information on a name that has been assumed to be a |
||
285 | /// template-name in order to permit a call via ADL. |
||
286 | AssumedTemplateStorage *getAsAssumedTemplateName() const; |
||
287 | |||
288 | /// Retrieve the substituted template template parameter, if |
||
289 | /// known. |
||
290 | /// |
||
291 | /// \returns The storage for the substituted template template parameter, |
||
292 | /// if known. Otherwise, returns NULL. |
||
293 | SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const; |
||
294 | |||
295 | /// Retrieve the substituted template template parameter pack, if |
||
296 | /// known. |
||
297 | /// |
||
298 | /// \returns The storage for the substituted template template parameter pack, |
||
299 | /// if known. Otherwise, returns NULL. |
||
300 | SubstTemplateTemplateParmPackStorage * |
||
301 | getAsSubstTemplateTemplateParmPack() const; |
||
302 | |||
303 | /// Retrieve the underlying qualified template name |
||
304 | /// structure, if any. |
||
305 | QualifiedTemplateName *getAsQualifiedTemplateName() const; |
||
306 | |||
307 | /// Retrieve the underlying dependent template name |
||
308 | /// structure, if any. |
||
309 | DependentTemplateName *getAsDependentTemplateName() const; |
||
310 | |||
311 | /// Retrieve the using shadow declaration through which the underlying |
||
312 | /// template declaration is introduced, if any. |
||
313 | UsingShadowDecl *getAsUsingShadowDecl() const; |
||
314 | |||
315 | TemplateName getUnderlying() const; |
||
316 | |||
317 | /// Get the template name to substitute when this template name is used as a |
||
318 | /// template template argument. This refers to the most recent declaration of |
||
319 | /// the template, including any default template arguments. |
||
320 | TemplateName getNameToSubstitute() const; |
||
321 | |||
322 | TemplateNameDependence getDependence() const; |
||
323 | |||
324 | /// Determines whether this is a dependent template name. |
||
325 | bool isDependent() const; |
||
326 | |||
327 | /// Determines whether this is a template name that somehow |
||
328 | /// depends on a template parameter. |
||
329 | bool isInstantiationDependent() const; |
||
330 | |||
331 | /// Determines whether this template name contains an |
||
332 | /// unexpanded parameter pack (for C++0x variadic templates). |
||
333 | bool containsUnexpandedParameterPack() const; |
||
334 | |||
335 | enum class Qualified { None, AsWritten, Fully }; |
||
336 | /// Print the template name. |
||
337 | /// |
||
338 | /// \param OS the output stream to which the template name will be |
||
339 | /// printed. |
||
340 | /// |
||
341 | /// \param Qual print the (Qualified::None) simple name, |
||
342 | /// (Qualified::AsWritten) any written (possibly partial) qualifier, or |
||
343 | /// (Qualified::Fully) the fully qualified name. |
||
344 | void print(raw_ostream &OS, const PrintingPolicy &Policy, |
||
345 | Qualified Qual = Qualified::AsWritten) const; |
||
346 | |||
347 | /// Debugging aid that dumps the template name. |
||
348 | void dump(raw_ostream &OS) const; |
||
349 | |||
350 | /// Debugging aid that dumps the template name to standard |
||
351 | /// error. |
||
352 | void dump() const; |
||
353 | |||
354 | void Profile(llvm::FoldingSetNodeID &ID) { |
||
355 | ID.AddPointer(Storage.getOpaqueValue()); |
||
356 | } |
||
357 | |||
358 | /// Retrieve the template name as a void pointer. |
||
359 | void *getAsVoidPointer() const { return Storage.getOpaqueValue(); } |
||
360 | |||
361 | /// Build a template name from a void pointer. |
||
362 | static TemplateName getFromVoidPointer(void *Ptr) { |
||
363 | return TemplateName(Ptr); |
||
364 | } |
||
365 | }; |
||
366 | |||
367 | /// Insertion operator for diagnostics. This allows sending TemplateName's |
||
368 | /// into a diagnostic with <<. |
||
369 | const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, |
||
370 | TemplateName N); |
||
371 | |||
372 | /// A structure for storing the information associated with a |
||
373 | /// substituted template template parameter. |
||
374 | class SubstTemplateTemplateParmStorage |
||
375 | : public UncommonTemplateNameStorage, public llvm::FoldingSetNode { |
||
376 | friend class ASTContext; |
||
377 | |||
378 | TemplateName Replacement; |
||
379 | Decl *AssociatedDecl; |
||
380 | |||
381 | SubstTemplateTemplateParmStorage(TemplateName Replacement, |
||
382 | Decl *AssociatedDecl, unsigned Index, |
||
383 | std::optional<unsigned> PackIndex) |
||
384 | : UncommonTemplateNameStorage(SubstTemplateTemplateParm, Index, |
||
385 | PackIndex ? *PackIndex + 1 : 0), |
||
386 | Replacement(Replacement), AssociatedDecl(AssociatedDecl) { |
||
387 | assert(AssociatedDecl != nullptr); |
||
388 | } |
||
389 | |||
390 | public: |
||
391 | /// A template-like entity which owns the whole pattern being substituted. |
||
392 | /// This will own a set of template parameters. |
||
393 | Decl *getAssociatedDecl() const { return AssociatedDecl; } |
||
394 | |||
395 | /// Returns the index of the replaced parameter in the associated declaration. |
||
396 | /// This should match the result of `getParameter()->getIndex()`. |
||
397 | unsigned getIndex() const { return Bits.Index; } |
||
398 | |||
399 | std::optional<unsigned> getPackIndex() const { |
||
400 | if (Bits.Data == 0) |
||
401 | return std::nullopt; |
||
402 | return Bits.Data - 1; |
||
403 | } |
||
404 | |||
405 | TemplateTemplateParmDecl *getParameter() const; |
||
406 | TemplateName getReplacement() const { return Replacement; } |
||
407 | |||
408 | void Profile(llvm::FoldingSetNodeID &ID); |
||
409 | |||
410 | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Replacement, |
||
411 | Decl *AssociatedDecl, unsigned Index, |
||
412 | std::optional<unsigned> PackIndex); |
||
413 | }; |
||
414 | |||
415 | inline TemplateName TemplateName::getUnderlying() const { |
||
416 | if (SubstTemplateTemplateParmStorage *subst |
||
417 | = getAsSubstTemplateTemplateParm()) |
||
418 | return subst->getReplacement().getUnderlying(); |
||
419 | return *this; |
||
420 | } |
||
421 | |||
422 | /// Represents a template name that was expressed as a |
||
423 | /// qualified name. |
||
424 | /// |
||
425 | /// This kind of template name refers to a template name that was |
||
426 | /// preceded by a nested name specifier, e.g., \c std::vector. Here, |
||
427 | /// the nested name specifier is "std::" and the template name is the |
||
428 | /// declaration for "vector". The QualifiedTemplateName class is only |
||
429 | /// used to provide "sugar" for template names that were expressed |
||
430 | /// with a qualified name, and has no semantic meaning. In this |
||
431 | /// manner, it is to TemplateName what ElaboratedType is to Type, |
||
432 | /// providing extra syntactic sugar for downstream clients. |
||
433 | class QualifiedTemplateName : public llvm::FoldingSetNode { |
||
434 | friend class ASTContext; |
||
435 | |||
436 | /// The nested name specifier that qualifies the template name. |
||
437 | /// |
||
438 | /// The bit is used to indicate whether the "template" keyword was |
||
439 | /// present before the template name itself. Note that the |
||
440 | /// "template" keyword is always redundant in this case (otherwise, |
||
441 | /// the template name would be a dependent name and we would express |
||
442 | /// this name with DependentTemplateName). |
||
443 | llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier; |
||
444 | |||
445 | /// The underlying template name, it is either |
||
446 | /// 1) a Template -- a template declaration that this qualified name refers |
||
447 | /// to. |
||
448 | /// 2) or a UsingTemplate -- a template declaration introduced by a |
||
449 | /// using-shadow declaration. |
||
450 | TemplateName UnderlyingTemplate; |
||
451 | |||
452 | QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, |
||
453 | TemplateName Template) |
||
454 | : Qualifier(NNS, TemplateKeyword ? 1 : 0), UnderlyingTemplate(Template) { |
||
455 | assert(UnderlyingTemplate.getKind() == TemplateName::Template || |
||
456 | UnderlyingTemplate.getKind() == TemplateName::UsingTemplate); |
||
457 | } |
||
458 | |||
459 | public: |
||
460 | /// Return the nested name specifier that qualifies this name. |
||
461 | NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } |
||
462 | |||
463 | /// Whether the template name was prefixed by the "template" |
||
464 | /// keyword. |
||
465 | bool hasTemplateKeyword() const { return Qualifier.getInt(); } |
||
466 | |||
467 | /// Return the underlying template name. |
||
468 | TemplateName getUnderlyingTemplate() const { return UnderlyingTemplate; } |
||
469 | |||
470 | void Profile(llvm::FoldingSetNodeID &ID) { |
||
471 | Profile(ID, getQualifier(), hasTemplateKeyword(), UnderlyingTemplate); |
||
472 | } |
||
473 | |||
474 | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
||
475 | bool TemplateKeyword, TemplateName TN) { |
||
476 | ID.AddPointer(NNS); |
||
477 | ID.AddBoolean(TemplateKeyword); |
||
478 | ID.AddPointer(TN.getAsVoidPointer()); |
||
479 | } |
||
480 | }; |
||
481 | |||
482 | /// Represents a dependent template name that cannot be |
||
483 | /// resolved prior to template instantiation. |
||
484 | /// |
||
485 | /// This kind of template name refers to a dependent template name, |
||
486 | /// including its nested name specifier (if any). For example, |
||
487 | /// DependentTemplateName can refer to "MetaFun::template apply", |
||
488 | /// where "MetaFun::" is the nested name specifier and "apply" is the |
||
489 | /// template name referenced. The "template" keyword is implied. |
||
490 | class DependentTemplateName : public llvm::FoldingSetNode { |
||
491 | friend class ASTContext; |
||
492 | |||
493 | /// The nested name specifier that qualifies the template |
||
494 | /// name. |
||
495 | /// |
||
496 | /// The bit stored in this qualifier describes whether the \c Name field |
||
497 | /// is interpreted as an IdentifierInfo pointer (when clear) or as an |
||
498 | /// overloaded operator kind (when set). |
||
499 | llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier; |
||
500 | |||
501 | /// The dependent template name. |
||
502 | union { |
||
503 | /// The identifier template name. |
||
504 | /// |
||
505 | /// Only valid when the bit on \c Qualifier is clear. |
||
506 | const IdentifierInfo *Identifier; |
||
507 | |||
508 | /// The overloaded operator name. |
||
509 | /// |
||
510 | /// Only valid when the bit on \c Qualifier is set. |
||
511 | OverloadedOperatorKind Operator; |
||
512 | }; |
||
513 | |||
514 | /// The canonical template name to which this dependent |
||
515 | /// template name refers. |
||
516 | /// |
||
517 | /// The canonical template name for a dependent template name is |
||
518 | /// another dependent template name whose nested name specifier is |
||
519 | /// canonical. |
||
520 | TemplateName CanonicalTemplateName; |
||
521 | |||
522 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
||
523 | const IdentifierInfo *Identifier) |
||
524 | : Qualifier(Qualifier, false), Identifier(Identifier), |
||
525 | CanonicalTemplateName(this) {} |
||
526 | |||
527 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
||
528 | const IdentifierInfo *Identifier, |
||
529 | TemplateName Canon) |
||
530 | : Qualifier(Qualifier, false), Identifier(Identifier), |
||
531 | CanonicalTemplateName(Canon) {} |
||
532 | |||
533 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
||
534 | OverloadedOperatorKind Operator) |
||
535 | : Qualifier(Qualifier, true), Operator(Operator), |
||
536 | CanonicalTemplateName(this) {} |
||
537 | |||
538 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
||
539 | OverloadedOperatorKind Operator, |
||
540 | TemplateName Canon) |
||
541 | : Qualifier(Qualifier, true), Operator(Operator), |
||
542 | CanonicalTemplateName(Canon) {} |
||
543 | |||
544 | public: |
||
545 | /// Return the nested name specifier that qualifies this name. |
||
546 | NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } |
||
547 | |||
548 | /// Determine whether this template name refers to an identifier. |
||
549 | bool isIdentifier() const { return !Qualifier.getInt(); } |
||
550 | |||
551 | /// Returns the identifier to which this template name refers. |
||
552 | const IdentifierInfo *getIdentifier() const { |
||
553 | assert(isIdentifier() && "Template name isn't an identifier?"); |
||
554 | return Identifier; |
||
555 | } |
||
556 | |||
557 | /// Determine whether this template name refers to an overloaded |
||
558 | /// operator. |
||
559 | bool isOverloadedOperator() const { return Qualifier.getInt(); } |
||
560 | |||
561 | /// Return the overloaded operator to which this template name refers. |
||
562 | OverloadedOperatorKind getOperator() const { |
||
563 | assert(isOverloadedOperator() && |
||
564 | "Template name isn't an overloaded operator?"); |
||
565 | return Operator; |
||
566 | } |
||
567 | |||
568 | void Profile(llvm::FoldingSetNodeID &ID) { |
||
569 | if (isIdentifier()) |
||
570 | Profile(ID, getQualifier(), getIdentifier()); |
||
571 | else |
||
572 | Profile(ID, getQualifier(), getOperator()); |
||
573 | } |
||
574 | |||
575 | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
||
576 | const IdentifierInfo *Identifier) { |
||
577 | ID.AddPointer(NNS); |
||
578 | ID.AddBoolean(false); |
||
579 | ID.AddPointer(Identifier); |
||
580 | } |
||
581 | |||
582 | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
||
583 | OverloadedOperatorKind Operator) { |
||
584 | ID.AddPointer(NNS); |
||
585 | ID.AddBoolean(true); |
||
586 | ID.AddInteger(Operator); |
||
587 | } |
||
588 | }; |
||
589 | |||
590 | } // namespace clang. |
||
591 | |||
592 | namespace llvm { |
||
593 | |||
594 | /// The clang::TemplateName class is effectively a pointer. |
||
595 | template<> |
||
596 | struct PointerLikeTypeTraits<clang::TemplateName> { |
||
597 | static inline void *getAsVoidPointer(clang::TemplateName TN) { |
||
598 | return TN.getAsVoidPointer(); |
||
599 | } |
||
600 | |||
601 | static inline clang::TemplateName getFromVoidPointer(void *Ptr) { |
||
602 | return clang::TemplateName::getFromVoidPointer(Ptr); |
||
603 | } |
||
604 | |||
605 | // No bits are available! |
||
606 | static constexpr int NumLowBitsAvailable = 0; |
||
607 | }; |
||
608 | |||
609 | } // namespace llvm. |
||
610 | |||
611 | #endif // LLVM_CLANG_AST_TEMPLATENAME_H |