Clang Project

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