/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 | | #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 | 178k | UncommonTemplateNameStorage(Kind Kind, unsigned Index, unsigned Data) { |
75 | 178k | Bits.Kind = Kind; |
76 | 178k | Bits.Index = Index; |
77 | 178k | Bits.Data = Data; |
78 | 178k | } |
79 | | |
80 | | public: |
81 | 417k | OverloadedTemplateStorage *getAsOverloadedStorage() { |
82 | 417k | return Bits.Kind == Overloaded |
83 | 417k | ? reinterpret_cast<OverloadedTemplateStorage *>(this)324k |
84 | 417k | : nullptr93.4k ; |
85 | 417k | } |
86 | | |
87 | 114k | AssumedTemplateStorage *getAsAssumedTemplateName() { |
88 | 114k | return Bits.Kind == Assumed |
89 | 114k | ? reinterpret_cast<AssumedTemplateStorage *>(this)488 |
90 | 114k | : nullptr113k ; |
91 | 114k | } |
92 | | |
93 | 212k | SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() { |
94 | 212k | return Bits.Kind == SubstTemplateTemplateParm |
95 | 212k | ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)212k |
96 | 212k | : nullptr78 ; |
97 | 212k | } |
98 | | |
99 | 245 | SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() { |
100 | 245 | return Bits.Kind == SubstTemplateTemplateParmPack |
101 | 245 | ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)10 |
102 | 245 | : nullptr235 ; |
103 | 245 | } |
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 | 157k | : UncommonTemplateNameStorage(Overloaded, 0, size) {} |
113 | | |
114 | 157k | NamedDecl **getStorage() { |
115 | 157k | return reinterpret_cast<NamedDecl **>(this + 1); |
116 | 157k | } |
117 | 162k | NamedDecl * const *getStorage() const { |
118 | 162k | return reinterpret_cast<NamedDecl *const *>(this + 1); |
119 | 162k | } |
120 | | |
121 | | public: |
122 | 0 | unsigned size() const { return Bits.Data; } |
123 | | |
124 | | using iterator = NamedDecl *const *; |
125 | | |
126 | 162k | iterator begin() const { return getStorage(); } |
127 | 5 | iterator end() const { return getStorage() + Bits.Data; } |
128 | | |
129 | 0 | llvm::ArrayRef<NamedDecl*> decls() const { |
130 | 0 | return llvm::ArrayRef(begin(), end()); |
131 | 0 | } |
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 | 7 | 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 | 5.59M | 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 | 8.11M | void *getAsVoidPointer() const { return Storage.getOpaqueValue(); } |
358 | | |
359 | | /// Build a template name from a void pointer. |
360 | 4.97M | static TemplateName getFromVoidPointer(void *Ptr) { |
361 | 4.97M | return TemplateName(Ptr); |
362 | 4.97M | } |
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 | 20.2k | : UncommonTemplateNameStorage(SubstTemplateTemplateParm, Index, |
383 | 20.2k | PackIndex ? *PackIndex + 116.4k : 03.82k ), |
384 | 20.2k | Replacement(Replacement), AssociatedDecl(AssociatedDecl) { |
385 | 20.2k | assert(AssociatedDecl != nullptr); |
386 | 20.2k | } |
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 | 48.9k | 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 | 48.9k | unsigned getIndex() const { return Bits.Index; } |
396 | | |
397 | 48.9k | std::optional<unsigned> getPackIndex() const { |
398 | 48.9k | if (Bits.Data == 0) |
399 | 8.04k | return std::nullopt; |
400 | 40.9k | return Bits.Data - 1; |
401 | 48.9k | } |
402 | | |
403 | | TemplateTemplateParmDecl *getParameter() const; |
404 | 118k | 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 | 9.90M | inline TemplateName TemplateName::getUnderlying() const { |
414 | 9.90M | if (SubstTemplateTemplateParmStorage *subst |
415 | 9.90M | = getAsSubstTemplateTemplateParm()) |
416 | 20.5k | return subst->getReplacement().getUnderlying(); |
417 | 9.88M | return *this; |
418 | 9.90M | } |
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 | 155k | : Qualifier(NNS, TemplateKeyword ? 137.4k : 0117k ), UnderlyingTemplate(Template) { |
453 | 155k | assert(UnderlyingTemplate.getKind() == TemplateName::Template || |
454 | 155k | UnderlyingTemplate.getKind() == TemplateName::UsingTemplate); |
455 | 155k | } |
456 | | |
457 | | public: |
458 | | /// Return the nested name specifier that qualifies this name. |
459 | 697k | NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } |
460 | | |
461 | | /// Whether the template name was prefixed by the "template" |
462 | | /// keyword. |
463 | 545k | bool hasTemplateKeyword() const { return Qualifier.getInt(); } |
464 | | |
465 | | /// Return the underlying template name. |
466 | 847k | TemplateName getUnderlyingTemplate() const { return UnderlyingTemplate; } |
467 | | |
468 | 544k | void Profile(llvm::FoldingSetNodeID &ID) { |
469 | 544k | Profile(ID, getQualifier(), hasTemplateKeyword(), UnderlyingTemplate); |
470 | 544k | } |
471 | | |
472 | | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
473 | 909k | bool TemplateKeyword, TemplateName TN) { |
474 | 909k | ID.AddPointer(NNS); |
475 | 909k | ID.AddBoolean(TemplateKeyword); |
476 | 909k | ID.AddPointer(TN.getAsVoidPointer()); |
477 | 909k | } |
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 | 30.6k | : Qualifier(Qualifier, false), Identifier(Identifier), |
523 | 30.6k | CanonicalTemplateName(this) {} |
524 | | |
525 | | DependentTemplateName(NestedNameSpecifier *Qualifier, |
526 | | const IdentifierInfo *Identifier, |
527 | | TemplateName Canon) |
528 | 49.1k | : Qualifier(Qualifier, false), Identifier(Identifier), |
529 | 49.1k | CanonicalTemplateName(Canon) {} |
530 | | |
531 | | DependentTemplateName(NestedNameSpecifier *Qualifier, |
532 | | OverloadedOperatorKind Operator) |
533 | 30 | : Qualifier(Qualifier, true), Operator(Operator), |
534 | 30 | CanonicalTemplateName(this) {} |
535 | | |
536 | | DependentTemplateName(NestedNameSpecifier *Qualifier, |
537 | | OverloadedOperatorKind Operator, |
538 | | TemplateName Canon) |
539 | 8 | : Qualifier(Qualifier, true), Operator(Operator), |
540 | 8 | CanonicalTemplateName(Canon) {} |
541 | | |
542 | | public: |
543 | | /// Return the nested name specifier that qualifies this name. |
544 | 169k | NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } |
545 | | |
546 | | /// Determine whether this template name refers to an identifier. |
547 | 347k | bool isIdentifier() const { return !Qualifier.getInt(); } |
548 | | |
549 | | /// Returns the identifier to which this template name refers. |
550 | 179k | const IdentifierInfo *getIdentifier() const { |
551 | 179k | assert(isIdentifier() && "Template name isn't an identifier?"); |
552 | 179k | return Identifier; |
553 | 179k | } |
554 | | |
555 | | /// Determine whether this template name refers to an overloaded |
556 | | /// operator. |
557 | 172 | bool isOverloadedOperator() const { return Qualifier.getInt(); } |
558 | | |
559 | | /// Return the overloaded operator to which this template name refers. |
560 | 172 | OverloadedOperatorKind getOperator() const { |
561 | 172 | assert(isOverloadedOperator() && |
562 | 172 | "Template name isn't an overloaded operator?"); |
563 | 172 | return Operator; |
564 | 172 | } |
565 | | |
566 | 139k | void Profile(llvm::FoldingSetNodeID &ID) { |
567 | 139k | if (isIdentifier()) |
568 | 139k | Profile(ID, getQualifier(), getIdentifier()); |
569 | 104 | else |
570 | 104 | Profile(ID, getQualifier(), getOperator()); |
571 | 139k | } |
572 | | |
573 | | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
574 | 246k | const IdentifierInfo *Identifier) { |
575 | 246k | ID.AddPointer(NNS); |
576 | 246k | ID.AddBoolean(false); |
577 | 246k | ID.AddPointer(Identifier); |
578 | 246k | } |
579 | | |
580 | | static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, |
581 | 186 | OverloadedOperatorKind Operator) { |
582 | 186 | ID.AddPointer(NNS); |
583 | 186 | ID.AddBoolean(true); |
584 | 186 | ID.AddInteger(Operator); |
585 | 186 | } |
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 | 4.31M | static inline void *getAsVoidPointer(clang::TemplateName TN) { |
596 | 4.31M | return TN.getAsVoidPointer(); |
597 | 4.31M | } |
598 | | |
599 | 4.33M | static inline clang::TemplateName getFromVoidPointer(void *Ptr) { |
600 | 4.33M | return clang::TemplateName::getFromVoidPointer(Ptr); |
601 | 4.33M | } |
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 |