//===- DeclCXX.h - Classes for representing C++ declarations --*- 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 // //===----------------------------------------------------------------------===// // /// \file /// Defines the C++ Decl subclasses, other than those for templates /// (found in DeclTemplate.h) and friends (in DeclFriend.h). // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_DECLCXX_H #define LLVM_CLANG_AST_DECLCXX_H #include "clang/AST/ASTUnresolvedSet.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/LambdaCapture.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/Stmt.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/UnresolvedSet.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Lambda.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/TrailingObjects.h" #include <cassert> #include <cstddef> #include <iterator> #include <memory> #include <vector> namespace clang { class ASTContext; class ClassTemplateDecl; class ConstructorUsingShadowDecl; class CXXBasePath; class CXXBasePaths; class CXXConstructorDecl; class CXXDestructorDecl; class CXXFinalOverriderMap; class CXXIndirectPrimaryBaseSet; class CXXMethodDecl; class DecompositionDecl; class FriendDecl; class FunctionTemplateDecl; class IdentifierInfo; class MemberSpecializationInfo; class BaseUsingDecl; class TemplateDecl; class TemplateParameterList; class UsingDecl; /// Represents an access specifier followed by colon ':'. /// /// An objects of this class represents sugar for the syntactic occurrence /// of an access specifier followed by a colon in the list of member /// specifiers of a C++ class definition. /// /// Note that they do not represent other uses of access specifiers, /// such as those occurring in a list of base specifiers. /// Also note that this class has nothing to do with so-called /// "access declarations" (C++98 11.3 [class.access.dcl]). class AccessSpecDecl : public Decl { … }; /// Represents a base class of a C++ class. /// /// Each CXXBaseSpecifier represents a single, direct base class (or /// struct) of a C++ class (or struct). It specifies the type of that /// base class, whether it is a virtual or non-virtual base, and what /// level of access (public, protected, private) is used for the /// derivation. For example: /// /// \code /// class A { }; /// class B { }; /// class C : public virtual A, protected B { }; /// \endcode /// /// In this code, C will have two CXXBaseSpecifiers, one for "public /// virtual A" and the other for "protected B". class CXXBaseSpecifier { … }; /// Represents a C++ struct/union/class. class CXXRecordDecl : public RecordDecl { … }; /// Store information needed for an explicit specifier. /// Used by CXXDeductionGuideDecl, CXXConstructorDecl and CXXConversionDecl. class ExplicitSpecifier { … }; /// Represents a C++ deduction guide declaration. /// /// \code /// template<typename T> struct A { A(); A(T); }; /// A() -> A<int>; /// \endcode /// /// In this example, there will be an explicit deduction guide from the /// second line, and implicit deduction guide templates synthesized from /// the constructors of \c A. class CXXDeductionGuideDecl : public FunctionDecl { … }; /// \brief Represents the body of a requires-expression. /// /// This decl exists merely to serve as the DeclContext for the local /// parameters of the requires expression as well as other declarations inside /// it. /// /// \code /// template<typename T> requires requires (T t) { {t++} -> regular; } /// \endcode /// /// In this example, a RequiresExpr object will be generated for the expression, /// and a RequiresExprBodyDecl will be created to hold the parameter t and the /// template argument list imposed by the compound requirement. class RequiresExprBodyDecl : public Decl, public DeclContext { … }; /// Represents a static or instance method of a struct/union/class. /// /// In the terminology of the C++ Standard, these are the (static and /// non-static) member functions, whether virtual or not. class CXXMethodDecl : public FunctionDecl { … }; /// Represents a C++ base or member initializer. /// /// This is part of a constructor initializer that /// initializes one non-static member variable or one base class. For /// example, in the following, both 'A(a)' and 'f(3.14159)' are member /// initializers: /// /// \code /// class A { }; /// class B : public A { /// float f; /// public: /// B(A& a) : A(a), f(3.14159) { } /// }; /// \endcode class CXXCtorInitializer final { … }; /// Description of a constructor that was inherited from a base class. class InheritedConstructor { … }; /// Represents a C++ constructor within a class. /// /// For example: /// /// \code /// class X { /// public: /// explicit X(int); // represented by a CXXConstructorDecl. /// }; /// \endcode class CXXConstructorDecl final : public CXXMethodDecl, private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor, ExplicitSpecifier> { … }; /// Represents a C++ destructor within a class. /// /// For example: /// /// \code /// class X { /// public: /// ~X(); // represented by a CXXDestructorDecl. /// }; /// \endcode class CXXDestructorDecl : public CXXMethodDecl { … }; /// Represents a C++ conversion function within a class. /// /// For example: /// /// \code /// class X { /// public: /// operator bool(); /// }; /// \endcode class CXXConversionDecl : public CXXMethodDecl { … }; /// Represents the language in a linkage specification. /// /// The values are part of the serialization ABI for /// ASTs and cannot be changed without altering that ABI. enum class LinkageSpecLanguageIDs { … }; /// Represents a linkage specification. /// /// For example: /// \code /// extern "C" void foo(); /// \endcode class LinkageSpecDecl : public Decl, public DeclContext { … }; /// Represents C++ using-directive. /// /// For example: /// \code /// using namespace std; /// \endcode /// /// \note UsingDirectiveDecl should be Decl not NamedDecl, but we provide /// artificial names for all using-directives in order to store /// them in DeclContext effectively. class UsingDirectiveDecl : public NamedDecl { … }; /// Represents a C++ namespace alias. /// /// For example: /// /// \code /// namespace Foo = Bar; /// \endcode class NamespaceAliasDecl : public NamedDecl, public Redeclarable<NamespaceAliasDecl> { … }; /// Implicit declaration of a temporary that was materialized by /// a MaterializeTemporaryExpr and lifetime-extended by a declaration class LifetimeExtendedTemporaryDecl final : public Decl, public Mergeable<LifetimeExtendedTemporaryDecl> { … }; /// Represents a shadow declaration implicitly introduced into a scope by a /// (resolved) using-declaration or using-enum-declaration to achieve /// the desired lookup semantics. /// /// For example: /// \code /// namespace A { /// void foo(); /// void foo(int); /// struct foo {}; /// enum bar { bar1, bar2 }; /// } /// namespace B { /// // add a UsingDecl and three UsingShadowDecls (named foo) to B. /// using A::foo; /// // adds UsingEnumDecl and two UsingShadowDecls (named bar1 and bar2) to B. /// using enum A::bar; /// } /// \endcode class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> { … }; /// Represents a C++ declaration that introduces decls from somewhere else. It /// provides a set of the shadow decls so introduced. class BaseUsingDecl : public NamedDecl { … }; /// Represents a C++ using-declaration. /// /// For example: /// \code /// using someNameSpace::someIdentifier; /// \endcode class UsingDecl : public BaseUsingDecl, public Mergeable<UsingDecl> { … }; /// Represents a shadow constructor declaration introduced into a /// class by a C++11 using-declaration that names a constructor. /// /// For example: /// \code /// struct Base { Base(int); }; /// struct Derived { /// using Base::Base; // creates a UsingDecl and a ConstructorUsingShadowDecl /// }; /// \endcode class ConstructorUsingShadowDecl final : public UsingShadowDecl { … }; /// Represents a C++ using-enum-declaration. /// /// For example: /// \code /// using enum SomeEnumTag ; /// \endcode class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> { … }; /// Represents a pack of using declarations that a single /// using-declarator pack-expanded into. /// /// \code /// template<typename ...T> struct X : T... { /// using T::operator()...; /// using T::operator T...; /// }; /// \endcode /// /// In the second case above, the UsingPackDecl will have the name /// 'operator T' (which contains an unexpanded pack), but the individual /// UsingDecls and UsingShadowDecls will have more reasonable names. class UsingPackDecl final : public NamedDecl, public Mergeable<UsingPackDecl>, private llvm::TrailingObjects<UsingPackDecl, NamedDecl *> { … }; /// Represents a dependent using declaration which was not marked with /// \c typename. /// /// Unlike non-dependent using declarations, these *only* bring through /// non-types; otherwise they would break two-phase lookup. /// /// \code /// template \<class T> class A : public Base<T> { /// using Base<T>::foo; /// }; /// \endcode class UnresolvedUsingValueDecl : public ValueDecl, public Mergeable<UnresolvedUsingValueDecl> { … }; /// Represents a dependent using declaration which was marked with /// \c typename. /// /// \code /// template \<class T> class A : public Base<T> { /// using typename Base<T>::foo; /// }; /// \endcode /// /// The type associated with an unresolved using typename decl is /// currently always a typename type. class UnresolvedUsingTypenameDecl : public TypeDecl, public Mergeable<UnresolvedUsingTypenameDecl> { … }; /// This node is generated when a using-declaration that was annotated with /// __attribute__((using_if_exists)) failed to resolve to a known declaration. /// In that case, Sema builds a UsingShadowDecl whose target is an instance of /// this declaration, adding it to the current scope. Referring to this /// declaration in any way is an error. class UnresolvedUsingIfExistsDecl final : public NamedDecl { … }; /// Represents a C++11 static_assert declaration. class StaticAssertDecl : public Decl { … }; /// A binding in a decomposition declaration. For instance, given: /// /// int n[3]; /// auto &[a, b, c] = n; /// /// a, b, and c are BindingDecls, whose bindings are the expressions /// x[0], x[1], and x[2] respectively, where x is the implicit /// DecompositionDecl of type 'int (&)[3]'. class BindingDecl : public ValueDecl { … }; /// A decomposition declaration. For instance, given: /// /// int n[3]; /// auto &[a, b, c] = n; /// /// the second line declares a DecompositionDecl of type 'int (&)[3]', and /// three BindingDecls (named a, b, and c). An instance of this class is always /// unnamed, but behaves in almost all other respects like a VarDecl. class DecompositionDecl final : public VarDecl, private llvm::TrailingObjects<DecompositionDecl, BindingDecl *> { … }; /// An instance of this class represents the declaration of a property /// member. This is a Microsoft extension to C++, first introduced in /// Visual Studio .NET 2003 as a parallel to similar features in C# /// and Managed C++. /// /// A property must always be a non-static class member. /// /// A property member superficially resembles a non-static data /// member, except preceded by a property attribute: /// __declspec(property(get=GetX, put=PutX)) int x; /// Either (but not both) of the 'get' and 'put' names may be omitted. /// /// A reference to a property is always an lvalue. If the lvalue /// undergoes lvalue-to-rvalue conversion, then a getter name is /// required, and that member is called with no arguments. /// If the lvalue is assigned into, then a setter name is required, /// and that member is called with one argument, the value assigned. /// Both operations are potentially overloaded. Compound assignments /// are permitted, as are the increment and decrement operators. /// /// The getter and putter methods are permitted to be overloaded, /// although their return and parameter types are subject to certain /// restrictions according to the type of the property. /// /// A property declared using an incomplete array type may /// additionally be subscripted, adding extra parameters to the getter /// and putter methods. class MSPropertyDecl : public DeclaratorDecl { … }; /// Parts of a decomposed MSGuidDecl. Factored out to avoid unnecessary /// dependencies on DeclCXX.h. struct MSGuidDeclParts { … }; /// A global _GUID constant. These are implicitly created by UuidAttrs. /// /// struct _declspec(uuid("01234567-89ab-cdef-0123-456789abcdef")) X{}; /// /// X is a CXXRecordDecl that contains a UuidAttr that references the (unique) /// MSGuidDecl for the specified UUID. class MSGuidDecl : public ValueDecl, public Mergeable<MSGuidDecl>, public llvm::FoldingSetNode { … }; /// An artificial decl, representing a global anonymous constant value which is /// uniquified by value within a translation unit. /// /// These is currently only used to back the LValue returned by /// __builtin_source_location, but could potentially be used for other similar /// situations in the future. class UnnamedGlobalConstantDecl : public ValueDecl, public Mergeable<UnnamedGlobalConstantDecl>, public llvm::FoldingSetNode { … }; /// Insertion operator for diagnostics. This allows sending an AccessSpecifier /// into a diagnostic with <<. const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, AccessSpecifier AS); } // namespace clang #endif // LLVM_CLANG_AST_DECLCXX_H