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 | LLVM_PREFERRED_TYPE(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 | |
356 | /// Retrieve the template name as a void pointer. |
357 | void *getAsVoidPointer() const { return Storage.getOpaqueValue(); } |
358 | |
359 | /// Build a template name from a void pointer. |
360 | static TemplateName getFromVoidPointer(void *Ptr) { |
361 | return TemplateName(Ptr); |
362 | } |
363 | }; |
364 | |
365 | /// Insertion operator for diagnostics. This allows sending TemplateName's |
366 | /// into a diagnostic with <<. |
367 | const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, |
368 | TemplateName N); |
369 | |
370 | /// A structure for storing the information associated with a |
371 | /// substituted template template parameter. |
372 | class SubstTemplateTemplateParmStorage |
373 | : public UncommonTemplateNameStorage, public llvm::FoldingSetNode { |
374 | friend class ASTContext; |
375 | |
376 | TemplateName Replacement; |
377 | Decl *AssociatedDecl; |
378 | |
379 | SubstTemplateTemplateParmStorage(TemplateName Replacement, |
380 | Decl *AssociatedDecl, unsigned Index, |
381 | std::optional<unsigned> PackIndex) |
382 | : UncommonTemplateNameStorage(SubstTemplateTemplateParm, Index, |
383 | PackIndex ? *PackIndex + 1 : 0), |
384 | Replacement(Replacement), AssociatedDecl(AssociatedDecl) { |
385 | assert(AssociatedDecl != nullptr); |
386 | } |
387 | |
388 | public: |
389 | /// A template-like entity which owns the whole pattern being substituted. |
390 | /// This will own a set of template parameters. |
391 | Decl *getAssociatedDecl() const { return AssociatedDecl; } |
392 | |
393 | /// Returns the index of the replaced parameter in the associated declaration. |
394 | /// This should match the result of `getParameter()->getIndex()`. |
395 | unsigned getIndex() const { return Bits.Index; } |
396 | |
397 | std::optional<unsigned> getPackIndex() const { |
398 | if (Bits.Data == 0) |
399 | return std::nullopt; |
400 | return Bits.Data - 1; |
401 | } |
402 | |
403 | TemplateTemplateParmDecl *getParameter() const; |
404 | TemplateName getReplacement() const { return Replacement; } |
405 | |
406 | void Profile(llvm::FoldingSetNodeID &ID); |
407 | |
408 | static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Replacement, |
409 | Decl *AssociatedDecl, unsigned Index, |
410 | std::optional<unsigned> PackIndex); |
411 | }; |
412 | |
413 | inline TemplateName TemplateName::getUnderlying() const { |
414 | if (SubstTemplateTemplateParmStorage *subst |
415 | = getAsSubstTemplateTemplateParm()) |
416 | return subst->getReplacement().getUnderlying(); |
417 | return *this; |
418 | } |
419 | |
420 | /// Represents a template name that was expressed as a |
421 | /// qualified name. |
422 | /// |
423 | /// This kind of template name refers to a template name that was |
424 | /// preceded by a nested name specifier, e.g., \c std::vector. Here, |
425 | /// the nested name specifier is "std::" and the template name is the |
426 | /// declaration for "vector". The QualifiedTemplateName class is only |
427 | /// used to provide "sugar" for template names that were expressed |
428 | /// with a qualified name, and has no semantic meaning. In this |
429 | /// manner, it is to TemplateName what ElaboratedType is to Type, |
430 | /// providing extra syntactic sugar for downstream clients. |
431 | class QualifiedTemplateName : public llvm::FoldingSetNode { |
432 | friend class ASTContext; |
433 | |
434 | /// The nested name specifier that qualifies the template name. |
435 | /// |
436 | /// The bit is used to indicate whether the "template" keyword was |
437 | /// present before the template name itself. Note that the |
438 | /// "template" keyword is always redundant in this case (otherwise, |
439 | /// the template name would be a dependent name and we would express |
440 | /// this name with DependentTemplateName). |
441 | llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier; |
442 | |
443 | /// The underlying template name, it is either |
444 | /// 1) a Template -- a template declaration that this qualified name refers |
445 | /// to. |
446 | /// 2) or a UsingTemplate -- a template declaration introduced by a |
447 | /// using-shadow declaration. |
448 | TemplateName UnderlyingTemplate; |
449 | |
450 | QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, |
451 | TemplateName Template) |
452 | : Qualifier(NNS, TemplateKeyword ? 1 : 0), UnderlyingTemplate(Template) { |
453 | assert(UnderlyingTemplate.getKind() == TemplateName::Template || |
454 | UnderlyingTemplate.getKind() == TemplateName::UsingTemplate); |
455 | } |
456 | |
457 | public: |
458 | /// Return the nested name specifier that qualifies this name. |
459 | NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } |
460 | |
461 | /// Whether the template name was prefixed by the "template" |
462 | /// keyword. |
463 | bool hasTemplateKeyword() const { return Qualifier.getInt(); } |
464 | |
465 | /// Return the underlying template name. |
466 | TemplateName getUnderlyingTemplate() const { return UnderlyingTemplate; } |
467 | |
468 | void Profile(llvm::FoldingSetNodeID &ID) { |
469 | Profile(ID, NNS: getQualifier(), TemplateKeyword: hasTemplateKeyword(), TN: UnderlyingTemplate); |
470 | } |
471 | |
472 | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
473 | bool TemplateKeyword, TemplateName TN) { |
474 | ID.AddPointer(Ptr: NNS); |
475 | ID.AddBoolean(B: TemplateKeyword); |
476 | ID.AddPointer(Ptr: TN.getAsVoidPointer()); |
477 | } |
478 | }; |
479 | |
480 | /// Represents a dependent template name that cannot be |
481 | /// resolved prior to template instantiation. |
482 | /// |
483 | /// This kind of template name refers to a dependent template name, |
484 | /// including its nested name specifier (if any). For example, |
485 | /// DependentTemplateName can refer to "MetaFun::template apply", |
486 | /// where "MetaFun::" is the nested name specifier and "apply" is the |
487 | /// template name referenced. The "template" keyword is implied. |
488 | class DependentTemplateName : public llvm::FoldingSetNode { |
489 | friend class ASTContext; |
490 | |
491 | /// The nested name specifier that qualifies the template |
492 | /// name. |
493 | /// |
494 | /// The bit stored in this qualifier describes whether the \c Name field |
495 | /// is interpreted as an IdentifierInfo pointer (when clear) or as an |
496 | /// overloaded operator kind (when set). |
497 | llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier; |
498 | |
499 | /// The dependent template name. |
500 | union { |
501 | /// The identifier template name. |
502 | /// |
503 | /// Only valid when the bit on \c Qualifier is clear. |
504 | const IdentifierInfo *Identifier; |
505 | |
506 | /// The overloaded operator name. |
507 | /// |
508 | /// Only valid when the bit on \c Qualifier is set. |
509 | OverloadedOperatorKind Operator; |
510 | }; |
511 | |
512 | /// The canonical template name to which this dependent |
513 | /// template name refers. |
514 | /// |
515 | /// The canonical template name for a dependent template name is |
516 | /// another dependent template name whose nested name specifier is |
517 | /// canonical. |
518 | TemplateName CanonicalTemplateName; |
519 | |
520 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
521 | const IdentifierInfo *Identifier) |
522 | : Qualifier(Qualifier, false), Identifier(Identifier), |
523 | CanonicalTemplateName(this) {} |
524 | |
525 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
526 | const IdentifierInfo *Identifier, |
527 | TemplateName Canon) |
528 | : Qualifier(Qualifier, false), Identifier(Identifier), |
529 | CanonicalTemplateName(Canon) {} |
530 | |
531 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
532 | OverloadedOperatorKind Operator) |
533 | : Qualifier(Qualifier, true), Operator(Operator), |
534 | CanonicalTemplateName(this) {} |
535 | |
536 | DependentTemplateName(NestedNameSpecifier *Qualifier, |
537 | OverloadedOperatorKind Operator, |
538 | TemplateName Canon) |
539 | : Qualifier(Qualifier, true), Operator(Operator), |
540 | CanonicalTemplateName(Canon) {} |
541 | |
542 | public: |
543 | /// Return the nested name specifier that qualifies this name. |
544 | NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } |
545 | |
546 | /// Determine whether this template name refers to an identifier. |
547 | bool isIdentifier() const { return !Qualifier.getInt(); } |
548 | |
549 | /// Returns the identifier to which this template name refers. |
550 | const IdentifierInfo *getIdentifier() const { |
551 | assert(isIdentifier() && "Template name isn't an identifier?" ); |
552 | return Identifier; |
553 | } |
554 | |
555 | /// Determine whether this template name refers to an overloaded |
556 | /// operator. |
557 | bool isOverloadedOperator() const { return Qualifier.getInt(); } |
558 | |
559 | /// Return the overloaded operator to which this template name refers. |
560 | OverloadedOperatorKind getOperator() const { |
561 | assert(isOverloadedOperator() && |
562 | "Template name isn't an overloaded operator?" ); |
563 | return Operator; |
564 | } |
565 | |
566 | void Profile(llvm::FoldingSetNodeID &ID) { |
567 | if (isIdentifier()) |
568 | Profile(ID, NNS: getQualifier(), Identifier: getIdentifier()); |
569 | else |
570 | Profile(ID, NNS: getQualifier(), Operator: getOperator()); |
571 | } |
572 | |
573 | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
574 | const IdentifierInfo *Identifier) { |
575 | ID.AddPointer(Ptr: NNS); |
576 | ID.AddBoolean(B: false); |
577 | ID.AddPointer(Ptr: Identifier); |
578 | } |
579 | |
580 | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
581 | OverloadedOperatorKind Operator) { |
582 | ID.AddPointer(Ptr: NNS); |
583 | ID.AddBoolean(B: true); |
584 | ID.AddInteger(I: Operator); |
585 | } |
586 | }; |
587 | |
588 | } // namespace clang. |
589 | |
590 | namespace llvm { |
591 | |
592 | /// The clang::TemplateName class is effectively a pointer. |
593 | template<> |
594 | struct PointerLikeTypeTraits<clang::TemplateName> { |
595 | static inline void *getAsVoidPointer(clang::TemplateName TN) { |
596 | return TN.getAsVoidPointer(); |
597 | } |
598 | |
599 | static inline clang::TemplateName getFromVoidPointer(void *Ptr) { |
600 | return clang::TemplateName::getFromVoidPointer(Ptr); |
601 | } |
602 | |
603 | // No bits are available! |
604 | static constexpr int NumLowBitsAvailable = 0; |
605 | }; |
606 | |
607 | } // namespace llvm. |
608 | |
609 | #endif // LLVM_CLANG_AST_TEMPLATENAME_H |
610 | |