//===- TemplateName.h - C++ Template Name Representation --------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the TemplateName interface and subclasses. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_TEMPLATENAME_H #define LLVM_CLANG_AST_TEMPLATENAME_H #include "clang/AST/DependenceFlags.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <cassert> #include <optional> namespace clang { class ASTContext; class Decl; class DependentTemplateName; class IdentifierInfo; class NamedDecl; class NestedNameSpecifier; enum OverloadedOperatorKind : int; class OverloadedTemplateStorage; class AssumedTemplateStorage; class DeducedTemplateStorage; struct PrintingPolicy; class QualifiedTemplateName; class SubstTemplateTemplateParmPackStorage; class SubstTemplateTemplateParmStorage; class TemplateArgument; class TemplateDecl; class TemplateTemplateParmDecl; class UsingShadowDecl; /// Implementation class used to describe either a set of overloaded /// template names or an already-substituted template template parameter pack. class UncommonTemplateNameStorage { … }; /// A structure for storing the information associated with an /// overloaded template name. class OverloadedTemplateStorage : public UncommonTemplateNameStorage { … }; /// A structure for storing an already-substituted template template /// parameter pack. /// /// This kind of template names occurs when the parameter pack has been /// provided with a template template argument pack in a context where its /// enclosing pack expansion could not be fully expanded. class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage, public llvm::FoldingSetNode { … }; struct DefaultArguments { … }; /// Represents a C++ template name within the type system. /// /// A C++ template name refers to a template within the C++ type /// system. In most cases, a template name is simply a reference to a /// class template, e.g. /// /// \code /// template<typename T> class X { }; /// /// X<int> xi; /// \endcode /// /// Here, the 'X' in \c X<int> is a template name that refers to the /// declaration of the class template X, above. Template names can /// also refer to function templates, C++0x template aliases, etc. /// /// Some template names are dependent. For example, consider: /// /// \code /// template<typename MetaFun, typename T1, typename T2> struct apply2 { /// typedef typename MetaFun::template apply<T1, T2>::type type; /// }; /// \endcode /// /// Here, "apply" is treated as a template name within the typename /// specifier in the typedef. "apply" is a nested template, and can /// only be understood in the context of a template instantiation, /// hence is represented as a dependent template name. class TemplateName { … }; /// Insertion operator for diagnostics. This allows sending TemplateName's /// into a diagnostic with <<. const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, TemplateName N); /// A structure for storing the information associated with a /// substituted template template parameter. class SubstTemplateTemplateParmStorage : public UncommonTemplateNameStorage, public llvm::FoldingSetNode { … }; class DeducedTemplateStorage : public UncommonTemplateNameStorage, public llvm::FoldingSetNode { … }; inline TemplateName TemplateName::getUnderlying() const { … } /// Represents a template name as written in source code. /// /// This kind of template name may refer to a template name that was /// preceded by a nested name specifier, e.g., \c std::vector. Here, /// the nested name specifier is "std::" and the template name is the /// declaration for "vector". It may also have been written with the /// 'template' keyword. The QualifiedTemplateName class is only /// used to provide "sugar" for template names, so that they can /// be differentiated from canonical template names. and has no /// semantic meaning. In this manner, it is to TemplateName what /// ElaboratedType is to Type, providing extra syntactic sugar /// for downstream clients. class QualifiedTemplateName : public llvm::FoldingSetNode { … }; /// Represents a dependent template name that cannot be /// resolved prior to template instantiation. /// /// This kind of template name refers to a dependent template name, /// including its nested name specifier (if any). For example, /// DependentTemplateName can refer to "MetaFun::template apply", /// where "MetaFun::" is the nested name specifier and "apply" is the /// template name referenced. The "template" keyword is implied. class DependentTemplateName : public llvm::FoldingSetNode { … }; } // namespace clang. namespace llvm { /// The clang::TemplateName class is effectively a pointer. template<> struct PointerLikeTypeTraits<clang::TemplateName> { … }; } // namespace llvm. #endif // LLVM_CLANG_AST_TEMPLATENAME_H