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