//===- Decl.h - Classes for representing 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 // //===----------------------------------------------------------------------===// // // This file defines the Decl subclasses. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_DECL_H #define LLVM_CLANG_AST_DECL_H #include "clang/AST/APNumericStorage.h" #include "clang/AST/APValue.h" #include "clang/AST/ASTContextAllocate.h" #include "clang/AST/DeclAccessPair.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/Type.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Linkage.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/Visibility.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" #include <cassert> #include <cstddef> #include <cstdint> #include <optional> #include <string> #include <utility> namespace clang { class ASTContext; struct ASTTemplateArgumentListInfo; class CompoundStmt; class DependentFunctionTemplateSpecializationInfo; class EnumDecl; class Expr; class FunctionTemplateDecl; class FunctionTemplateSpecializationInfo; class FunctionTypeLoc; class LabelStmt; class MemberSpecializationInfo; class Module; class NamespaceDecl; class ParmVarDecl; class RecordDecl; class Stmt; class StringLiteral; class TagDecl; class TemplateArgumentList; class TemplateArgumentListInfo; class TemplateParameterList; class TypeAliasTemplateDecl; class UnresolvedSetImpl; class VarTemplateDecl; enum class ImplicitParamKind; /// The top declaration context. class TranslationUnitDecl : public Decl, public DeclContext, public Redeclarable<TranslationUnitDecl> { … }; /// Represents a `#pragma comment` line. Always a child of /// TranslationUnitDecl. class PragmaCommentDecl final : public Decl, private llvm::TrailingObjects<PragmaCommentDecl, char> { … }; /// Represents a `#pragma detect_mismatch` line. Always a child of /// TranslationUnitDecl. class PragmaDetectMismatchDecl final : public Decl, private llvm::TrailingObjects<PragmaDetectMismatchDecl, char> { … }; /// Declaration context for names declared as extern "C" in C++. This /// is neither the semantic nor lexical context for such declarations, but is /// used to check for conflicts with other extern "C" declarations. Example: /// /// \code /// namespace N { extern "C" void f(); } // #1 /// void N::f() {} // #2 /// namespace M { extern "C" void f(); } // #3 /// \endcode /// /// The semantic context of #1 is namespace N and its lexical context is the /// LinkageSpecDecl; the semantic context of #2 is namespace N and its lexical /// context is the TU. However, both declarations are also visible in the /// extern "C" context. /// /// The declaration at #3 finds it is a redeclaration of \c N::f through /// lookup in the extern "C" context. class ExternCContextDecl : public Decl, public DeclContext { … }; /// This represents a decl that may have a name. Many decls have names such /// as ObjCMethodDecl, but not \@class, etc. /// /// Note that not every NamedDecl is actually named (e.g., a struct might /// be anonymous), and not every name is an identifier. class NamedDecl : public Decl { … }; inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) { … } /// Represents the declaration of a label. Labels also have a /// corresponding LabelStmt, which indicates the position that the label was /// defined at. For normal labels, the location of the decl is the same as the /// location of the statement. For GNU local labels (__label__), the decl /// location is where the __label__ is. class LabelDecl : public NamedDecl { … }; /// Represent a C++ namespace. class NamespaceDecl : public NamedDecl, public DeclContext, public Redeclarable<NamespaceDecl> { … }; class VarDecl; /// Represent the declaration of a variable (in which case it is /// an lvalue) a function (in which case it is a function designator) or /// an enum constant. class ValueDecl : public NamedDecl { … }; /// A struct with extended info about a syntactic /// name qualifier, to be used for the case of out-of-line declarations. struct QualifierInfo { … }; /// Represents a ValueDecl that came out of a declarator. /// Contains type source information through TypeSourceInfo. class DeclaratorDecl : public ValueDecl { … }; /// Structure used to store a statement, the constant value to /// which it was evaluated (if any), and whether or not the statement /// is an integral constant expression (if known). struct EvaluatedStmt { … }; /// Represents a variable declaration or definition. class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> { … }; /// Defines the kind of the implicit parameter: is this an implicit parameter /// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured /// context or something else. enum class ImplicitParamKind { … }; class ImplicitParamDecl : public VarDecl { … }; /// Represents a parameter to a function. class ParmVarDecl : public VarDecl { … }; enum class MultiVersionKind { … }; /// Represents a function declaration or definition. /// /// Since a given function can be declared several times in a program, /// there may be several FunctionDecls that correspond to that /// function. Only one of those FunctionDecls will be found when /// traversing the list of declarations in the context of the /// FunctionDecl (e.g., the translation unit); this FunctionDecl /// contains all of the information known about the function. Other, /// previous declarations of the function are available via the /// getPreviousDecl() chain. class FunctionDecl : public DeclaratorDecl, public DeclContext, public Redeclarable<FunctionDecl> { … }; /// Represents a member of a struct/union/class. class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { … }; /// An instance of this object exists for each enum constant /// that is defined. For example, in "enum X {a,b}", each of a/b are /// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a /// TagType for the X EnumDecl. class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl>, public APIntStorage { … }; /// Represents a field injected from an anonymous union/struct into the parent /// scope. These are always implicit. class IndirectFieldDecl : public ValueDecl, public Mergeable<IndirectFieldDecl> { … }; /// Represents a declaration of a type. class TypeDecl : public NamedDecl { … }; /// Base class for declarations which introduce a typedef-name. class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> { … }; /// Represents the declaration of a typedef-name via the 'typedef' /// type specifier. class TypedefDecl : public TypedefNameDecl { … }; /// Represents the declaration of a typedef-name via a C++11 /// alias-declaration. class TypeAliasDecl : public TypedefNameDecl { … }; /// Represents the declaration of a struct/union/class/enum. class TagDecl : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> { … }; /// Represents an enum. In C++11, enums can be forward-declared /// with a fixed underlying type, and in C we allow them to be forward-declared /// with no underlying type as an extension. class EnumDecl : public TagDecl { … }; /// Enum that represents the different ways arguments are passed to and /// returned from function calls. This takes into account the target-specific /// and version-specific rules along with the rules determined by the /// language. enum class RecordArgPassingKind { … }; /// Represents a struct/union/class. For example: /// struct X; // Forward declaration, no "body". /// union Y { int A, B; }; // Has body with members A and B (FieldDecls). /// This decl will be marked invalid if *any* members are invalid. class RecordDecl : public TagDecl { … }; class FileScopeAsmDecl : public Decl { … }; /// A declaration that models statements at global scope. This declaration /// supports incremental and interactive C/C++. /// /// \note This is used in libInterpreter, clang -cc1 -fincremental-extensions /// and in tools such as clang-repl. class TopLevelStmtDecl : public Decl, public DeclContext { … }; /// Represents a block literal declaration, which is like an /// unnamed FunctionDecl. For example: /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } class BlockDecl : public Decl, public DeclContext { … }; /// Represents the body of a CapturedStmt, and serves as its DeclContext. class CapturedDecl final : public Decl, public DeclContext, private llvm::TrailingObjects<CapturedDecl, ImplicitParamDecl *> { … }; /// Describes a module import declaration, which makes the contents /// of the named module visible in the current translation unit. /// /// An import declaration imports the named module (or submodule). For example: /// \code /// @import std.vector; /// \endcode /// /// A C++20 module import declaration imports the named module or partition. /// Periods are permitted in C++20 module names, but have no semantic meaning. /// For example: /// \code /// import NamedModule; /// import :SomePartition; // Must be a partition of the current module. /// import Names.Like.this; // Allowed. /// import :and.Also.Partition.names; /// \endcode /// /// Import declarations can also be implicitly generated from /// \#include/\#import directives. class ImportDecl final : public Decl, llvm::TrailingObjects<ImportDecl, SourceLocation> { … }; /// Represents a standard C++ module export declaration. /// /// For example: /// \code /// export void foo(); /// \endcode class ExportDecl final : public Decl, public DeclContext { … }; /// Represents an empty-declaration. class EmptyDecl : public Decl { … }; /// HLSLBufferDecl - Represent a cbuffer or tbuffer declaration. class HLSLBufferDecl final : public NamedDecl, public DeclContext { … }; /// Insertion operator for diagnostics. This allows sending NamedDecl's /// into a diagnostic with <<. inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD, const NamedDecl *ND) { … } template<typename decl_type> void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { … } // Inline function definitions. /// Check if the given decl is complete. /// /// We use this function to break a cycle between the inline definitions in /// Type.h and Decl.h. inline bool IsEnumDeclComplete(EnumDecl *ED) { … } /// Check if the given decl is scoped. /// /// We use this function to break a cycle between the inline definitions in /// Type.h and Decl.h. inline bool IsEnumDeclScoped(EnumDecl *ED) { … } /// OpenMP variants are mangled early based on their OpenMP context selector. /// The new name looks likes this: /// <name> + OpenMPVariantManglingSeparatorStr + <mangled OpenMP context> static constexpr StringRef getOpenMPVariantManglingSeparatorStr() { … } /// Returns whether the given FunctionDecl has an __arm[_locally]_streaming /// attribute. bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming); } // namespace clang #endif // LLVM_CLANG_AST_DECL_H