//===--- Decl.h - Swift Language Declaration ASTs ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // This file defines the Decl class and subclasses. // //===----------------------------------------------------------------------===// #ifndef SWIFT_DECL_H #define SWIFT_DECL_H #include "swift/AST/Attr.h" #include "swift/AST/CaptureInfo.h" #include "swift/AST/DeclContext.h" #include "swift/AST/DefaultArgumentKind.h" #include "swift/AST/KnownProtocols.h" #include "swift/AST/Identifier.h" #include "swift/AST/Requirement.h" #include "swift/AST/Substitution.h" #include "swift/AST/Type.h" #include "swift/AST/TypeLoc.h" #include "swift/Basic/SourceLoc.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallPtrSet.h" #include namespace clang { class Decl; class MacroInfo; } namespace swift { class ArchetypeType; class ASTContext; class ASTWalker; class Type; class Expr; class LiteralExpr; class FuncDecl; class BraceStmt; class DeclAttributes; class GenericTypeParamDecl; class GenericTypeParamType; class Module; class NameAliasType; class EnumElementDecl; class Pattern; struct PrintOptions; class ProtocolDecl; class ProtocolType; enum class Resilience : unsigned char; class TypeAliasDecl; class Stmt; class SubscriptDecl; class ValueDecl; class VarDecl; typedef llvm::PointerUnion ClangNode; enum class DeclKind : uint8_t { #define DECL(Id, Parent) Id, #define DECL_RANGE(Id, FirstId, LastId) \ First_##Id##Decl = FirstId, Last_##Id##Decl = LastId, #include "swift/AST/DeclNodes.def" }; /// Keeps track of stage of circularity checking for the given protocol. enum class CircularityCheck { /// Circularity has not yet been checked. Unchecked, /// We're currently checking circularity. Checking, /// Circularity has already been checked. Checked }; /// Decl - Base class for all declarations in Swift. class alignas(8) Decl { // alignas(8) because we use three tag bits on Decl*. class DeclBitfields { friend class Decl; unsigned Kind : 8; /// \brief Whether this declaration is invalid. unsigned Invalid : 1; /// \brief Whether this declaration was implicitly created, e.g., /// an implicit constructor in a struct. unsigned Implicit : 1; /// \brief Whether this declaration was mapped directly from a Clang AST. /// /// Use getClangAST() to retrieve the corresponding Clang AST. unsigned FromClang : 1; }; enum { NumDeclBits = 11 }; static_assert(NumDeclBits <= 32, "fits in an unsigned"); class PatternBindingDeclBitfields { friend class PatternBindingDecl; unsigned : NumDeclBits; /// \brief Whether this pattern binding declares static variables. unsigned IsStatic : 1; }; enum { NumPatternBindingDeclBits = 1 }; static_assert(NumPatternBindingDeclBits <= 32, "fits in an unsigned"); class ValueDeclBitfields { friend class ValueDecl; unsigned : NumDeclBits; unsigned ConformsToProtocolRequrement : 1; }; enum { NumValueDeclBits = NumDeclBits + 1 }; static_assert(NumValueDeclBits <= 32, "fits in an unsigned"); class VarDeclBitfields { friend class VarDecl; unsigned : NumValueDeclBits; /// \brief Whether this property is a type property (currently unfortunately /// called 'static'). unsigned Static : 1; }; enum { NumVarDeclBits = NumValueDeclBits + 1 }; static_assert(NumVarDeclBits <= 32, "fits in an unsigned"); class AbstractFunctionDeclBitfields { friend class AbstractFunctionDecl; unsigned : NumValueDeclBits; /// \see AbstractFunctionDecl::BodyKind unsigned BodyKind : 2; /// \brief Whether this function was declared with a selector-style /// signature. unsigned HasSelectorStyleSignature : 1; }; enum { NumAbstractFunctionDeclBits = NumValueDeclBits + 3 }; static_assert(NumAbstractFunctionDeclBits <= 32, "fits in an unsigned"); class FuncDeclBitfields { friend class FuncDecl; unsigned : NumAbstractFunctionDeclBits; /// \brief Whether this function is a 'static' method. unsigned Static : 1; /// \brief Number of parameter patterns (tuples). unsigned NumParamPatterns : 16; }; enum { NumFuncDeclBits = NumAbstractFunctionDeclBits + 17 }; static_assert(NumFuncDeclBits <= 32, "fits in an unsigned"); class TypeDeclBitfields { friend class TypeDecl; unsigned : NumValueDeclBits; /// Whether we have already checked the inheritance clause. /// /// FIXME: Is this too fine-grained? unsigned CheckedInheritanceClause : 1; /// Whether we have already set the protocols to which this type conforms. unsigned ProtocolsSet : 1; }; enum { NumTypeDeclBits = NumValueDeclBits + 2 }; static_assert(NumTypeDeclBits <= 32, "fits in an unsigned"); enum { NumNominalTypeDeclBits = NumTypeDeclBits}; static_assert(NumNominalTypeDeclBits <= 32, "fits in an unsigned"); class ProtocolDeclBitfields { friend class ProtocolDecl; unsigned : NumNominalTypeDeclBits; /// Whether the \c RequiresClass bit is valid. unsigned RequiresClassValid : 1; /// Whether this is a [class_bounded] protocol. unsigned RequiresClass : 1; /// Whether the \c ExistentialConformsToSelf bit is valid. unsigned ExistentialConformsToSelfValid : 1; /// Whether the existential of this protocol conforms to itself. unsigned ExistentialConformsToSelf : 1; /// If this is a compiler-known protocol, this will be a KnownProtocolKind /// value, plus one. Otherwise, it will be 0. unsigned KnownProtocol : 5; /// The stage of the circularity check for this protocol. unsigned Circularity : 2; }; enum { NumProtocolDeclBits = NumNominalTypeDeclBits + 11 }; static_assert(NumProtocolDeclBits <= 32, "fits in an unsigned"); class ClassDeclBitfields { friend class ClassDecl; unsigned : NumNominalTypeDeclBits; /// The stage of the inheritance circularity check for this class. unsigned Circularity : 2; }; enum { NumClassDeclBits = NumNominalTypeDeclBits + 2 }; static_assert(NumClassDeclBits <= 32, "fits in an unsigned"); class EnumDeclBitfields { friend class EnumDecl; unsigned : NumNominalTypeDeclBits; /// The stage of the raw type circularity check for this class. unsigned Circularity : 2; }; enum { NumEnumDeclBits = NumNominalTypeDeclBits + 2 }; static_assert(NumEnumDeclBits <= 32, "fits in an unsigned"); class InfixOperatorDeclBitfields { friend class InfixOperatorDecl; unsigned : NumDeclBits; unsigned Associativity : 2; unsigned Precedence : 8; }; enum { NumInfixOperatorDeclBits = NumDeclBits + 10 }; static_assert(NumInfixOperatorDeclBits <= 32, "fits in an unsigned"); class ImportDeclBitfields { friend class ImportDecl; unsigned : NumDeclBits; unsigned ImportKind : 3; unsigned IsExported : 1; }; enum { NumImportDeclBits = NumDeclBits + 4 }; static_assert(NumImportDeclBits <= 32, "fits in an unsigned"); class ExtensionDeclBitfields { friend class ExtensionDecl; unsigned : NumDeclBits; /// Whether we have already checked the inheritance clause. /// /// FIXME: Is this too fine-grained? unsigned CheckedInheritanceClause : 1; }; enum { NumExtensionDeclBits = NumDeclBits + 4 }; static_assert(NumExtensionDeclBits <= 32, "fits in an unsigned"); protected: union { DeclBitfields DeclBits; PatternBindingDeclBitfields PatternBindingDeclBits; ValueDeclBitfields ValueDeclBits; AbstractFunctionDeclBitfields AbstractFunctionDeclBits; VarDeclBitfields VarDeclBits; FuncDeclBitfields FuncDeclBits; TypeDeclBitfields TypeDeclBits; ProtocolDeclBitfields ProtocolDeclBits; ClassDeclBitfields ClassDeclBits; EnumDeclBitfields EnumDeclBits; InfixOperatorDeclBitfields InfixOperatorDeclBits; ImportDeclBitfields ImportDeclBits; ExtensionDeclBitfields ExtensionDeclBits; }; private: DeclContext *Context; Decl(const Decl&) = delete; void operator=(const Decl&) = delete; protected: // Storage for the declaration attributes. llvm::PointerIntPair AttrsAndIsObjC; static const DeclAttributes EmptyAttrs; Decl(DeclKind kind, DeclContext *DC) : Context(DC), AttrsAndIsObjC(&EmptyAttrs, false) { DeclBits.Kind = unsigned(kind); DeclBits.Invalid = false; DeclBits.Implicit = false; DeclBits.FromClang = false; } ClangNode getClangNodeSlow(); public: DeclKind getKind() const { return DeclKind(DeclBits.Kind); } /// \brief Retrieve the name of the given declaration kind. /// /// This name should only be used for debugging dumps and other /// developer aids, and should never be part of a diagnostic or exposed /// to the user of the compiler in any way. static StringRef getKindName(DeclKind K); DeclContext *getDeclContext() const { return Context; } void setDeclContext(DeclContext *DC) { Context = DC; } /// Retrieve the innermost declaration context corresponding to this /// declaration, which will either be the declaration itself (if it's /// also a declaration context) or its declaration context. DeclContext *getInnermostDeclContext(); /// \brief Retrieve the module in which this declaration resides. Module *getModuleContext() const; /// getASTContext - Return the ASTContext that this decl lives in. ASTContext &getASTContext() const { assert(Context && "Decl doesn't have an assigned context"); return Context->getASTContext(); } DeclAttributes &getMutableAttrs(); const DeclAttributes &getAttrs() const { return *AttrsAndIsObjC.getPointer(); } SourceLoc getStartLoc() const { return getSourceRange().Start; } SourceLoc getEndLoc() const { return getSourceRange().End; } SourceLoc getLoc() const; SourceRange getSourceRange() const; SourceLoc TrailingSemiLoc; LLVM_ATTRIBUTE_DEPRECATED( void dump() const LLVM_ATTRIBUTE_USED, "only for use within the debugger"); void dump(raw_ostream &OS, unsigned Indent = 0) const; /// \brief Pretty-print the given declaration. /// /// \param OS Output stream to which the declaration will be printed. void print(raw_ostream &OS) const; /// \brief Pretty-print the given declaration. /// /// \param os Output stream to which the declaration will be printed. /// /// \param options Options to control how pretty-printing is performed. /// /// \param declOffsets If non-null, will be populated with the stream offsets /// at which each declaration encountered is printed. void print(raw_ostream &os, const PrintOptions &options, SmallVectorImpl> *declOffsets = nullptr) const; /// \brief Determine whether this declaration should be printed when /// encountered in its declaration context's list of members. bool shouldPrintInContext() const; bool walk(ASTWalker &walker); /// \brief Should this declaration be treated as if annotated with transparent /// attribute. bool isTransparent() const; /// \brief Return whether this declaration has been determined invalid. bool isInvalid() const { return DeclBits.Invalid; } /// \brief Mark this declaration invalid. void setInvalid() { DeclBits.Invalid = true; } /// \brief Determine whether this declaration was implicitly generated by the /// compiler (rather than explicitly written in source code). bool isImplicit() const { return DeclBits.Implicit; } /// \brief Mark this declaration as implicit. void setImplicit() { DeclBits.Implicit = true; } /// \brief Returns true if there is a Clang AST node associated /// with self. bool hasClangNode() const { return DeclBits.FromClang; } /// \brief Retrieve the Clang AST node from which this declaration was /// synthesized, if any. ClangNode getClangNode() { if (!DeclBits.FromClang) return ClangNode(); return getClangNodeSlow(); } /// \brief Retrieve the Clang declaration from which this declaration was /// synthesized, if any. const clang::Decl *getClangDecl() { if (!DeclBits.FromClang) return nullptr; return getClangNodeSlow().dyn_cast(); } /// \brief Retrieve the Clang macro from which this declaration was /// synthesized, if any. clang::MacroInfo *getClangMacro() { if (!DeclBits.FromClang) return nullptr; return getClangNodeSlow().dyn_cast(); } /// \brief Set the Clang node associated with this declaration. void setClangNode(ClangNode node); // Make vanilla new/delete illegal for Decls. void *operator new(size_t Bytes) = delete; void operator delete(void *Data) = delete; // Only allow allocation of Decls using the allocator in ASTContext // or by doing a placement new. void *operator new(size_t Bytes, ASTContext &C, unsigned Alignment = alignof(Decl)); void *operator new(size_t Bytes, void *Mem) { assert(Mem); return Mem; } }; /// GenericParam - A parameter to a generic function or type, as declared in /// the list of generic parameters, e.g., the T and U in: /// /// \code /// func f(t : T, u : U) { /* ... */ } /// \endcode class GenericParam { GenericTypeParamDecl *TypeParam; public: /// Construct a generic parameter from a type parameter. GenericParam(GenericTypeParamDecl *TypeParam) : TypeParam(TypeParam) { } /// getDecl - Retrieve the generic parameter declaration. ValueDecl *getDecl() const { return reinterpret_cast(TypeParam); } /// getAsTypeParam - Retrieve the generic parameter as a type parameter. GenericTypeParamDecl *getAsTypeParam() const { return TypeParam; } /// setDeclContext - Set the declaration context for the generic parameter, /// once it is known. void setDeclContext(DeclContext *DC); }; /// \brief A single requirement in a 'where' clause, which places additional /// restrictions on the generic parameters or associated types of a generic /// function, type, or protocol. /// /// This always represents a requirement spelled in the source code. It is /// never generated implicitly. class RequirementRepr { SourceLoc SeparatorLoc; RequirementKind Kind : 1; bool Invalid : 1; TypeLoc Types[2]; RequirementRepr(SourceLoc SeparatorLoc, RequirementKind Kind, TypeLoc FirstType, TypeLoc SecondType) : SeparatorLoc(SeparatorLoc), Kind(Kind), Invalid(false), Types{FirstType, SecondType} { } public: /// \brief Construct a new conformance requirement. /// /// \param Subject The type that must conform to the given protocol or /// composition, or be a subclass of the given class type. /// \param ColonLoc The location of the ':', or an invalid location if /// this requirement was implied. /// \param Constraint The protocol or protocol composition to which the /// subject must conform, or superclass from which the subject must inherit. static RequirementRepr getConformance(TypeLoc Subject, SourceLoc ColonLoc, TypeLoc Constraint) { return { ColonLoc, RequirementKind::Conformance, Subject, Constraint }; } /// \brief Construct a new same-type requirement. /// /// \param FirstType The first type. /// \param EqualLoc The location of the '==' in the same-type constraint, or /// an invalid location if this requirement was implied. /// \param SecondType The second type. static RequirementRepr getSameType(TypeLoc FirstType, SourceLoc EqualLoc, TypeLoc SecondType) { return { EqualLoc, RequirementKind::SameType, FirstType, SecondType }; } /// \brief Determine the kind of requirement RequirementKind getKind() const { return Kind; } /// \brief Determine whether this requirement is invalid. bool isInvalid() const { return Invalid; } /// \brief Mark this requirement invalid. void setInvalid() { Invalid = true; } /// \brief For a conformance requirement, return the subject of the /// conformance relationship. Type getSubject() const { assert(getKind() == RequirementKind::Conformance); return Types[0].getType(); } TypeRepr *getSubjectRepr() const { assert(getKind() == RequirementKind::Conformance); return Types[0].getTypeRepr(); } TypeLoc &getSubjectLoc() { assert(getKind() == RequirementKind::Conformance); return Types[0]; } const TypeLoc &getSubjectLoc() const { assert(getKind() == RequirementKind::Conformance); return Types[0]; } /// \brief For a conformance requirement, return the protocol or to which /// the subject conforms or superclass it inherits. Type getConstraint() const { assert(getKind() == RequirementKind::Conformance); return Types[1].getType(); } TypeLoc &getConstraintLoc() { assert(getKind() == RequirementKind::Conformance); return Types[1]; } /// \brief Retrieve the location of the ':' in an explicitly-written /// conformance requirement. SourceLoc getColonLoc() const { assert(getKind() == RequirementKind::Conformance); return SeparatorLoc; } /// \brief Retrieve the first type of a same-type requirement. Type getFirstType() const { assert(getKind() == RequirementKind::SameType); return Types[0].getType(); } TypeRepr *getFirstTypeRepr() const { assert(getKind() == RequirementKind::SameType); return Types[0].getTypeRepr(); } TypeLoc &getFirstTypeLoc() { assert(getKind() == RequirementKind::SameType); return Types[0]; } const TypeLoc &getFirstTypeLoc() const { assert(getKind() == RequirementKind::SameType); return Types[0]; } /// \brief Retrieve the second type of a same-type requirement. Type getSecondType() const { assert(getKind() == RequirementKind::SameType); return Types[1].getType(); } TypeRepr *getSecondTypeRepr() const { assert(getKind() == RequirementKind::SameType); return Types[1].getTypeRepr(); } TypeLoc &getSecondTypeLoc() { assert(getKind() == RequirementKind::SameType); return Types[1]; } const TypeLoc &getSecondTypeLoc() const { assert(getKind() == RequirementKind::SameType); return Types[1]; } /// \brief Retrieve the location of the '==' in an explicitly-written /// same-type requirement. SourceLoc getEqualLoc() const { assert(getKind() == RequirementKind::SameType); return SeparatorLoc; } }; /// GenericParamList - A list of generic parameters that is part of a generic /// function or type, along with extra requirements placed on those generic /// parameters and types derived from them. class GenericParamList { SourceRange Brackets; unsigned NumParams; SourceLoc WhereLoc; MutableArrayRef Requirements; ArrayRef AllArchetypes; GenericParamList *OuterParameters; GenericParamList(SourceLoc LAngleLoc, ArrayRef Params, SourceLoc WhereLoc, MutableArrayRef Requirements, SourceLoc RAngleLoc); public: /// create - Create a new generic parameter list within the given AST context. /// /// \param Context The ASTContext in which the generic parameter list will /// be allocated. /// \param LAngleLoc The location of the opening angle bracket ('<') /// \param Params The list of generic parameters, which will be copied into /// ASTContext-allocated memory. /// \param RAngleLoc The location of the closing angle bracket ('>') static GenericParamList *create(ASTContext &Context, SourceLoc LAngleLoc, ArrayRef Params, SourceLoc RAngleLoc); /// create - Create a new generic parameter list and "where" clause within /// the given AST context. /// /// \param Context The ASTContext in which the generic parameter list will /// be allocated. /// \param LAngleLoc The location of the opening angle bracket ('<') /// \param Params The list of generic parameters, which will be copied into /// ASTContext-allocated memory. /// \param WhereLoc The location of the 'where' keyword, if any. /// \param Requirements The list of requirements, which will be copied into /// ASTContext-allocated memory. /// \param RAngleLoc The location of the closing angle bracket ('>') static GenericParamList *create(const ASTContext &Context, SourceLoc LAngleLoc, ArrayRef Params, SourceLoc WhereLoc, MutableArrayRef Requirements, SourceLoc RAngleLoc); MutableArrayRef getParams() { return MutableArrayRef( reinterpret_cast(this + 1), NumParams); } ArrayRef getParams() const { return ArrayRef( reinterpret_cast(this + 1), NumParams); } unsigned size() const { return NumParams; } GenericParam *begin() { return getParams().begin(); } GenericParam *end() { return getParams().end(); } const GenericParam *begin() const { return getParams().begin(); } const GenericParam *end() const { return getParams().end(); } /// \brief Retrieve the location of the 'where' keyword, or an invalid /// location if 'where' was not present. SourceLoc getWhereLoc() const { return WhereLoc; } /// \brief Retrieve the set of additional requirements placed on these /// generic parameters and types derived from them. /// /// This list may contain both explicitly-written requirements as well as /// implicitly-generated requirements, and may be non-empty even if no /// 'where' keyword is present. MutableArrayRef getRequirements() { return Requirements; } /// \brief Retrieve the set of additional requirements placed on these /// generic parameters and types derived from them. /// /// This list may contain both explicitly-written requirements as well as /// implicitly-generated requirements, and may be non-empty even if no /// 'where' keyword is present. ArrayRef getRequirements() const { return Requirements; } /// \brief Override the set of requirements associated with this generic /// parameter list. /// /// \param NewRequirements The new set of requirements, which is expected /// to be a superset of the existing set of requirements (although this /// property is not checked here). It is assumed that the array reference /// refers to ASTContext-allocated memory. void overrideRequirements(MutableArrayRef NewRequirements) { Requirements = NewRequirements; } /// \brief Retrieves the list containing all archetypes described by this /// generic parameter clause. /// /// In this list of archetypes, the primary archetypes come first followed by /// any non-primary archetypes (i.e., those archetypes that encode associated /// types of another archetype). ArrayRef getAllArchetypes() const { return AllArchetypes; } /// \brief Retrieves the list containing only the primary archetypes described /// by this generic parameter clause. This excludes archetypes for associated /// types of the primary archetypes. ArrayRef getPrimaryArchetypes() const { return getAllArchetypes().slice(0, size()); } /// \brief Retrieves the list containing only the associated archetypes. ArrayRef getAssociatedArchetypes() const { return getAllArchetypes().slice(size()); } /// \brief Sets all archetypes *without* copying the source array. void setAllArchetypes(ArrayRef AA) { AllArchetypes = AA; } /// \brief Retrieve the outer generic parameter list, which provides the /// generic parameters of the context in which this generic parameter list /// exists. /// /// Consider the following generic class: /// /// \code /// class Vector { /// constructor(range : R) { } /// } /// \endcode /// /// The generic parameter list has no outer parameters, because it is /// the outermost generic parameter list. The generic parameter list /// for the constructor has the generic parameter list as /// its outer generic parameter list. GenericParamList *getOuterParameters() const { return OuterParameters; } /// \brief Set the outer generic parameter list. See \c getOuterParameters /// for more information. void setOuterParameters(GenericParamList *Outer) { OuterParameters = Outer; } SourceRange getSourceRange() const { return Brackets; } /// Retrieve the depth of this generic parameter list. unsigned getDepth() const { unsigned depth = 0; for (auto gp = getOuterParameters(); gp; gp = gp->getOuterParameters()) ++depth; return depth; } }; /// Describes what kind of name is being imported. /// /// If the enumerators here are changed, make sure to update all diagnostics /// using ImportKind as a select index. enum class ImportKind : uint8_t { Module = 0, Type, Struct, Class, Enum, Protocol, Var, Func }; /// ImportDecl - This represents a single import declaration, e.g.: /// import swift /// import typealias swift.Int class ImportDecl : public Decl { public: typedef std::pair AccessPathElement; private: SourceLoc ImportLoc; SourceLoc KindLoc; /// The number of elements in this path. unsigned NumPathElements; AccessPathElement *getPathBuffer() { return reinterpret_cast(this+1); } const AccessPathElement *getPathBuffer() const { return reinterpret_cast(this+1); } ImportDecl(DeclContext *DC, SourceLoc ImportLoc, ImportKind K, SourceLoc KindLoc, bool Exported, ArrayRef Path); public: static ImportDecl *create(ASTContext &C, DeclContext *DC, SourceLoc ImportLoc, ImportKind Kind, SourceLoc KindLoc, bool Exported, ArrayRef Path); ArrayRef getFullAccessPath() const { return ArrayRef(getPathBuffer(), NumPathElements); } ArrayRef getModulePath() const { auto result = getFullAccessPath(); if (getImportKind() != ImportKind::Module) result = result.slice(0, result.size()-1); return result; } ArrayRef getDeclPath() const { if (getImportKind() == ImportKind::Module) return {}; return getFullAccessPath().back(); } ImportKind getImportKind() const { return static_cast(ImportDeclBits.ImportKind); } bool isExported() const { return ImportDeclBits.IsExported; } SourceLoc getStartLoc() const { return ImportLoc; } SourceLoc getLoc() const { return getFullAccessPath().front().second; } SourceRange getSourceRange() const { return SourceRange(ImportLoc, getFullAccessPath().back().second); } SourceLoc getKindLoc() const { return KindLoc; } static bool classof(const Decl *D) { return D->getKind() == DeclKind::Import; } }; /// ExtensionDecl - This represents a type extension containing methods /// associated with the type. This is not a ValueDecl and has no Type because /// there are no runtime values of the Extension's type. class ExtensionDecl : public Decl, public DeclContext { SourceLoc ExtensionLoc; // Location of 'extension' keyword. SourceRange Braces; /// ExtendedType - The type being extended. TypeLoc ExtendedType; MutableArrayRef Inherited; ArrayRef Members; /// \brief The set of protocols to which this extension conforms. ArrayRef Protocols; /// \brief The set of protocol conformance mappings. The element order /// corresponds to the order of Protocols. ArrayRef Conformances; /// \brief The next extension in the linked list of extensions. /// /// The bit indicates whether this extension has been resolved to refer to /// a known nominal type. llvm::PointerIntPair NextExtension = {nullptr, false}; friend class ExtensionIterator; friend class NominalTypeDecl; friend class MemberLookupTable; public: using Decl::getASTContext; ExtensionDecl(SourceLoc ExtensionLoc, TypeLoc ExtendedType, MutableArrayRef Inherited, DeclContext *Parent) : Decl(DeclKind::Extension, Parent), DeclContext(DeclContextKind::ExtensionDecl, Parent), ExtensionLoc(ExtensionLoc), ExtendedType(ExtendedType), Inherited(Inherited) { ExtensionDeclBits.CheckedInheritanceClause = false; } SourceLoc getStartLoc() const { return ExtensionLoc; } SourceLoc getLoc() const { return ExtensionLoc; } SourceRange getSourceRange() const { return { ExtensionLoc, Braces.End }; } SourceRange getBraces() const { return Braces; } Type getExtendedType() const { return ExtendedType.getType(); } TypeLoc &getExtendedTypeLoc() { return ExtendedType; } /// \brief Retrieve the set of protocols that this type inherits (i.e, /// explicitly conforms to). MutableArrayRef getInherited() { return Inherited; } ArrayRef getInherited() const { return Inherited; } /// Whether we already type-checked the inheritance clause. bool checkedInheritanceClause() const { return ExtensionDeclBits.CheckedInheritanceClause; } /// Note that we have already type-checked the inheritance clause. void setCheckedInheritanceClause(bool checked = true) { ExtensionDeclBits.CheckedInheritanceClause = checked; } /// \brief Retrieve the set of protocols to which this extension conforms. ArrayRef getProtocols() const { return Protocols; } void setProtocols(ArrayRef protocols) { Protocols = protocols; } /// \brief Retrieve the set of protocol conformance mappings for this type. /// /// Calculated during type-checking. ArrayRef getConformances() const { return Conformances; } void setConformances(ArrayRef c); ArrayRef getMembers() const { return Members; } void setMembers(ArrayRef M, SourceRange B); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == DeclKind::Extension; } static bool classof(const DeclContext *C) { return C->getContextKind() == DeclContextKind::ExtensionDecl; } using DeclContext::operator new; }; /// \brief Iterator that walks the extensions of a particular type. class ExtensionIterator { ExtensionDecl *current; public: ExtensionIterator() : current() { } explicit ExtensionIterator(ExtensionDecl *current) : current(current) { } ExtensionDecl *operator*() const { return current; } ExtensionDecl *operator->() const { return current; } ExtensionIterator &operator++() { current = current->NextExtension.getPointer(); return *this; } ExtensionIterator operator++(int) { ExtensionIterator tmp = *this; ++(*this); return tmp; } friend bool operator==(ExtensionIterator x, ExtensionIterator y) { return x.current == y.current; } friend bool operator!=(ExtensionIterator x, ExtensionIterator y) { return x.current != y.current; } }; /// \brief Range that covers a set of extensions. class ExtensionRange { ExtensionIterator first; ExtensionIterator last; public: ExtensionRange(ExtensionIterator first, ExtensionIterator last) : first(first), last(last) { } typedef ExtensionIterator iterator; iterator begin() const { return first; } iterator end() const { return last; } }; // PatternBindingDecl - This decl contains a pattern and optional initializer // for a set of one or more VarDecls declared together. (For example, in // "var (a,b) = foo()", this contains the pattern "(a,b)" and the intializer // "foo()". The same applies to simpler declarations like "var a = foo()".) class PatternBindingDecl : public Decl { SourceLoc StaticLoc; ///< Location of the 'static' keyword, if present. SourceLoc VarLoc; ///< Location of the 'var' keyword. Pattern *Pat; ///< The pattern this decl binds. /// The initializer, and whether it's been type-checked already. llvm::PointerIntPair InitAndChecked; friend class Decl; public: PatternBindingDecl(SourceLoc StaticLoc, SourceLoc VarLoc, Pattern *Pat, Expr *E, DeclContext *Parent) : Decl(DeclKind::PatternBinding, Parent), StaticLoc(StaticLoc), VarLoc(VarLoc), Pat(Pat), InitAndChecked(E, false) { PatternBindingDeclBits.IsStatic = StaticLoc.isValid(); } SourceLoc getStartLoc() const { return StaticLoc.isValid() ? StaticLoc : VarLoc; } SourceLoc getLoc() const { return VarLoc; } SourceRange getSourceRange() const; Pattern *getPattern() { return Pat; } const Pattern *getPattern() const { return Pat; } void setPattern(Pattern *P) { Pat = P; } bool hasInit() const { return InitAndChecked.getPointer(); } Expr *getInit() const { return InitAndChecked.getPointer(); } bool wasInitChecked() const { return InitAndChecked.getInt(); } void setInit(Expr *expr, bool checked) { InitAndChecked.setPointerAndInt(expr, checked); } bool isStatic() const { return PatternBindingDeclBits.IsStatic; } void setStatic(bool s) { PatternBindingDeclBits.IsStatic = s; } static bool classof(const Decl *D) { return D->getKind() == DeclKind::PatternBinding; } }; /// TopLevelCodeDecl - This decl is used as a container for top-level /// expressions and statements in the main module. It is always a direct /// child of the body of a TranslationUnit. The primary reason for /// building these is to give top-level statements a DeclContext which is /// distinct from the TranslationUnit itself. This, among other things, /// makes it easier to distinguish between local top-level variables (which /// are not live past the end of the statement) and global variables. class TopLevelCodeDecl : public Decl, public DeclContext { BraceStmt *Body; public: TopLevelCodeDecl(DeclContext *Parent, BraceStmt *Body = nullptr) : Decl(DeclKind::TopLevelCode, Parent), DeclContext(DeclContextKind::TopLevelCodeDecl, Parent), Body(Body) {} BraceStmt *getBody() const { return Body; } void setBody(BraceStmt *b) { Body = b; } SourceLoc getStartLoc() const; SourceLoc getLoc() const { return getStartLoc(); } SourceRange getSourceRange() const; static bool classof(const Decl *D) { return D->getKind() == DeclKind::TopLevelCode; } static bool classof(const DeclContext *C) { return C->getContextKind() == DeclContextKind::TopLevelCodeDecl; } using DeclContext::operator new; }; /// ValueDecl - All named decls that are values in the language. These can /// have a type, etc. class ValueDecl : public Decl { Identifier Name; SourceLoc NameLoc; Type Ty; protected: ValueDecl(DeclKind K, DeclContext *DC, Identifier name, SourceLoc NameLoc) : Decl(K, DC), Name(name), NameLoc(NameLoc) { ValueDeclBits.ConformsToProtocolRequrement = false; } /// The interface type, mutable because some subclasses compute this lazily. mutable Type InterfaceTy; public: /// \brief Return true if this is a definition of a decl, not a forward /// declaration (e.g. of a function) that is implemented outside of the /// swift code. bool isDefinition() const; Identifier getName() const { return Name; } bool isOperator() const { return Name.isOperator(); } SourceLoc getNameLoc() const { return NameLoc; } SourceLoc getLoc() const { return NameLoc; } bool hasType() const { return !Ty.isNull(); } Type getType() const { assert(!Ty.isNull() && "declaration has no type set yet"); return Ty; } /// Set the type of this declaration for the first time. void setType(Type T); /// Overwrite the type of this declaration. void overwriteType(Type T); /// Get the innermost declaration context that can provide generic /// parameters used within this declaration. DeclContext *getPotentialGenericDeclContext(); /// Retrieve the "interface" type of this value, which is the type used when /// the declaration is viewed from the outside. For a generic function, /// this will have generic function type using generic parameters rather than /// archetypes, while a generic nominal type's interface type will be the /// generic type specialized with its generic parameters. /// /// FIXME: Eventually, this will simply become the type of the value, and /// we will substitute in the appropriate archetypes within a particular /// context. Type getInterfaceType() const; /// Set the interface type for the given value. void setInterfaceType(Type type) { InterfaceTy = type; } /// isReferencedAsLValue - Returns 'true' if references to this /// declaration are l-values. bool isReferencedAsLValue() const { return getKind() == DeclKind::Var; } /// isSettable - Determine whether references to this decl may appear /// on the left-hand side of an assignment or as the operand of a /// `&` or [assignment] operator. bool isSettable() const; /// Determine whether references to this decl are settable in the /// above sense when used on a base of the given type (which may be /// null to indicate that there is no base). bool isSettableOnBase(Type baseType) const; /// isInstanceMember - Determine whether this value is an instance member /// of an enum or protocol. bool isInstanceMember() const; /// needsCapture - Check whether referring to this decl from a nested /// function requires capturing it. bool needsCapture() const; /// Retrieve the declaration that this declaration overrides, if any. ValueDecl *getOverriddenDecl() const; /// isObjC - Returns true if the decl requires Objective-C interop. bool isObjC() const { return AttrsAndIsObjC.getInt(); } void setIsObjC(bool value) { AttrsAndIsObjC.setInt(value); } /// Returns true if this decl can be found by id-style dynamic lookup. bool canBeAccessedByDynamicLookup() const; /// Returns true if this decl conforms to a protocol requirement. bool conformsToProtocolRequirement() const { return ValueDeclBits.ConformsToProtocolRequrement; } void setConformsToProtocolRequirement(bool Value = true) { ValueDeclBits.ConformsToProtocolRequrement = Value; } /// Returns the protocol requirements that this decl conforms to. ArrayRef getConformances(); /// Dump a reference to the given declaration. void dumpRef(raw_ostream &os) const; /// Dump a reference to the given declaration. void dumpRef() const; static bool classof(const Decl *D) { return D->getKind() >= DeclKind::First_ValueDecl && D->getKind() <= DeclKind::Last_ValueDecl; } }; /// This is a common base class for declarations which declare a type. class TypeDecl : public ValueDecl { MutableArrayRef Inherited; /// \brief The set of protocols to which this type conforms. ArrayRef Protocols; /// \brief The set of protocol conformance mappings. The element order /// corresponds to the order of Protocols. ArrayRef Conformances; protected: TypeDecl(DeclKind K, DeclContext *DC, Identifier name, SourceLoc NameLoc, MutableArrayRef inherited) : ValueDecl(K, DC, name, NameLoc), Inherited(inherited) { TypeDeclBits.CheckedInheritanceClause = false; TypeDeclBits.ProtocolsSet = false; } bool isProtocolsValid() const { return TypeDeclBits.ProtocolsSet; } public: Type getDeclaredType() const; Type getDeclaredInterfaceType() const; /// \brief Retrieve the set of protocols that this type inherits (i.e, /// explicitly conforms to). MutableArrayRef getInherited() { return Inherited; } ArrayRef getInherited() const { return Inherited; } /// Whether we already type-checked the inheritance clause. bool checkedInheritanceClause() const { return TypeDeclBits.CheckedInheritanceClause; } /// Note that we have already type-checked the inheritance clause. void setCheckedInheritanceClause(bool checked = true) { TypeDeclBits.CheckedInheritanceClause = checked; } /// \brief Retrieve the set of protocols to which this type conforms. /// /// FIXME: Include protocol conformance from extensions? This will require /// semantic analysis to compute. ArrayRef getProtocols() const { return Protocols; } void setProtocols(ArrayRef protocols) { assert((!TypeDeclBits.ProtocolsSet || protocols.empty()) && "protocols already set"); TypeDeclBits.ProtocolsSet = true; Protocols = protocols; } /// \brief True if the type can implicitly derive a conformance for the given /// protocol. /// /// If true, explicit conformance checking will synthesize implicit /// declarations for requirements of the protocol that are not satisfied by /// the type's explicit members. bool derivesProtocolConformance(ProtocolDecl *protocol) const; /// \brief Retrieve the set of protocol conformance mappings for this type. /// /// Calculated during type-checking. ArrayRef getConformances() const { return Conformances; } void setConformances(ArrayRef c); void setInherited(MutableArrayRef i) { Inherited = i; } static bool classof(const Decl *D) { return D->getKind() >= DeclKind::First_TypeDecl && D->getKind() <= DeclKind::Last_TypeDecl; } }; /// TypeAliasDecl - This is a declaration of a typealias, for example: /// /// typealias foo = int /// /// TypeAliasDecl's always have 'MetaTypeType' type. /// class TypeAliasDecl : public TypeDecl { /// The type that represents this (sugared) name alias. mutable NameAliasType *AliasTy; SourceLoc TypeAliasLoc; // The location of the 'typalias' keyword TypeLoc UnderlyingTy; public: TypeAliasDecl(SourceLoc TypeAliasLoc, Identifier Name, SourceLoc NameLoc, TypeLoc UnderlyingTy, DeclContext *DC, MutableArrayRef Inherited); SourceLoc getStartLoc() const { return TypeAliasLoc; } SourceRange getSourceRange() const; /// getUnderlyingType - Returns the underlying type, which is /// assumed to have been set. Type getUnderlyingType() const { assert(!UnderlyingTy.getType().isNull() && "getting invalid underlying type"); return UnderlyingTy.getType(); } /// \brief Determine whether this type alias has an underlying type. bool hasUnderlyingType() const { return !UnderlyingTy.getType().isNull(); } TypeLoc &getUnderlyingTypeLoc() { return UnderlyingTy; } /// getAliasType - Return the sugared version of this decl as a Type. NameAliasType *getAliasType() const { return AliasTy; } static bool classof(const Decl *D) { return D->getKind() == DeclKind::TypeAlias; } }; /// Abstract class describing generic type parameters and associated types, /// whose common purpose is to anchor the abstract type parameter and specify /// requirements for any corresponding type argument. class AbstractTypeParamDecl : public TypeDecl { /// The superclass of the generic parameter. Type SuperclassTy; /// The archetype describing this abstract type parameter within its scope. ArchetypeType *Archetype; protected: AbstractTypeParamDecl(DeclKind kind, DeclContext *dc, Identifier name, SourceLoc NameLoc) : TypeDecl(kind, dc, name, NameLoc, { }), Archetype(nullptr) { } public: /// Return the superclass of the generic parameter. Type getSuperclass() const { return SuperclassTy; } /// Set the superclass of the generic parameter. void setSuperclass(Type superclassTy) { SuperclassTy = superclassTy; } /// Retrieve the archetype that describes this abstract type parameter /// within its scope. ArchetypeType *getArchetype() const { return Archetype; } /// Set the archetype used to describe this abstract type parameter within /// its scope. void setArchetype(ArchetypeType *archetype) { Archetype = archetype; } static bool classof(const Decl *D) { return D->getKind() >= DeclKind::First_AbstractTypeParamDecl && D->getKind() <= DeclKind::Last_AbstractTypeParamDecl; } }; /// A declaration of a generic type parameter. /// /// A generic type parameter introduces a new, named type parameter along /// with some set of requirements on any type argument used to realize this /// type parameter. The requirements involve conformances to specific /// protocols or inheritance from a specific class type. /// /// In the following example, 'T' is a generic type parameter with the /// requirement that the type argument conform to the 'Comparable' protocol. /// /// \code /// func min(x : T, y : T) -> T { ... } /// \endcode class GenericTypeParamDecl : public AbstractTypeParamDecl { unsigned Depth : 16; unsigned Index : 16; public: /// Construct a new generic type parameter. /// /// \param dc The DeclContext in which the generic type parameter's owner /// occurs. This should later be overwritten with the actual declaration /// context that owns the type parameter. /// /// \param name The name of the generic parameter. /// \param nameLoc The location of the name. GenericTypeParamDecl(DeclContext *dc, Identifier name, SourceLoc nameLoc, unsigned depth, unsigned index); /// The depth of this generic type parameter, i.e., the number of outer /// levels of generic parameter lists that enclose this type parameter. /// /// \code /// struct X { /// func f() { } /// } /// \endcode /// /// Here 'T' has depth 0 and 'U' has depth 1. Both have index 0. unsigned getDepth() const { return Depth; } /// Set the depth of this generic type parameter. /// /// \sa getDepth void setDepth(unsigned depth) { Depth = depth; } /// The index of this generic type parameter within its generic parameter /// list. /// /// \code /// struct X { /// func f() { } /// } /// \endcode /// /// Here 'T' and 'U' have indexes 0 and 1, respectively. 'V' has index 0. unsigned getIndex() const { return Index; } SourceLoc getStartLoc() const { return getNameLoc(); } SourceRange getSourceRange() const; static bool classof(const Decl *D) { return D->getKind() == DeclKind::GenericTypeParam; } }; /// A declaration of an associated type. /// /// An associated type introduces a new, named type in a protocol that /// can vary from one conforming type to the next. Associated types have a /// set of requirements to which the type that replaces it much realize, /// describes via conformance to specific protocols, or inheritance from a /// specific class type. /// /// In the following example, 'Element' is an associated type with no /// requirements. /// /// \code /// protocol Enumerator { /// typealias Element /// func getNext() -> Element? /// } /// \endcode /// /// Every protocol has an implicitly-created associated type 'Self' that /// describes a type that conforms to the protocol. class AssociatedTypeDecl : public AbstractTypeParamDecl { /// The location of the initial keyword. SourceLoc KeywordLoc; public: AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc, Identifier name, SourceLoc nameLoc); /// Get the protocol in which this associated type is declared. ProtocolDecl *getProtocol() const { return cast(getDeclContext()); } SourceLoc getStartLoc() const { return KeywordLoc; } SourceRange getSourceRange() const; static bool classof(const Decl *D) { return D->getKind() == DeclKind::AssociatedType; } }; class MemberLookupTable; /// A class for iterating local declarations of a nominal type that are of /// the given FilterDeclType and for which the FilterPredicate function returns /// true. template class DeclFilterRange { public: class iterator { /// The remaining declarations. We need both ends here so that /// operator++ knows when to stop. /// /// Invariant: either this is empty or its first element matches the /// filter conditions. ArrayRef Remaining; friend class DeclFilterRange; iterator(ArrayRef remaining) : Remaining(remaining) {} void skipNonMatching() { while (!Remaining.empty()) { if (auto filtered = dyn_cast(Remaining.front())) if (FilterPredicate(filtered)) return; Remaining = Remaining.slice(1); } } public: inline FilterDeclType *operator*() const { assert(!Remaining.empty() && "dereferencing empty iterator!"); return cast(Remaining.front()); } iterator &operator++() { assert(!Remaining.empty() && "incrementing empty iterator!"); Remaining = Remaining.slice(1); skipNonMatching(); return *this; } iterator operator++(int) { iterator old = *this; ++*this; return old; } friend bool operator==(iterator lhs, iterator rhs) { assert(lhs.Remaining.end() == rhs.Remaining.end() && "comparing iterators from different sources?"); return lhs.Remaining.begin() == rhs.Remaining.begin(); } friend bool operator!=(iterator lhs, iterator rhs) { return !(lhs == rhs); } }; private: /// Our iterator is actually a pretty reasonable representation of /// the range itself. iterator Members; public: DeclFilterRange(ArrayRef allMembers) : Members(allMembers) { // Establish the iterator's invariant. Members.skipNonMatching(); } bool empty() const { return Members.Remaining.empty(); } iterator begin() const { return Members; } iterator end() const { // For the benefit of operator==, construct a range whose // begin() is the end of the members array. auto endRange = Members.Remaining.slice(Members.Remaining.size()); return iterator(endRange); } FilterDeclType *front() const { return *begin(); } }; /// Describes the generic signature of a particular declaration, including /// both the generic type parameters and the requirements placed on those /// generic parameters. class GenericSignature { unsigned NumGenericParams; unsigned NumRequirements; // Make vanilla new/delete illegal. void *operator new(size_t Bytes) = delete; void operator delete(void *Data) = delete; /// Retrieve a mutable version of the generic parameters. MutableArrayRef getGenericParamsBuffer() { return { reinterpret_cast(this + 1), NumGenericParams }; } /// Retrieve a mutable verison of the requirements. MutableArrayRef getRequirementsBuffer() { void *genericParams = getGenericParamsBuffer().end(); return { reinterpret_cast(genericParams), NumRequirements }; } GenericSignature(ArrayRef params, ArrayRef requirements); public: /// Create a new generic signature with the given type parameters and /// requirements. static GenericSignature *get(ArrayRef params, ArrayRef requirements, ASTContext &ctx); /// Retrieve the generic parameters. ArrayRef getGenericParams() const { return { reinterpret_cast(this + 1), NumGenericParams }; } /// Retrieve the requirements. ArrayRef getRequirements() const { const void *genericParams = getGenericParams().end(); return { reinterpret_cast(genericParams), NumRequirements }; } // Only allow allocation by doing a placement new. void *operator new(size_t Bytes, void *Mem) { assert(Mem); return Mem; } }; /// NominalTypeDecl - a declaration of a nominal type, like a struct. This /// decl is always a DeclContext. class NominalTypeDecl : public TypeDecl, public DeclContext { SourceRange Braces; ArrayRef Members; GenericParamList *GenericParams; /// \brief The generic signature of this type. /// /// This is the semantic representation of a generic parameters and the /// requirements placed on them. /// /// FIXME: The generic parameters here are also derivable from /// \c GenericParams. However, we likely want to make \c GenericParams /// the parsed representation, and not part of the module file. GenericSignature *GenericSig = nullptr; /// \brief The first extension of this type. ExtensionDecl *FirstExtension = nullptr; /// \brief The last extension of this type, used solely for efficient /// insertion of new extensions. ExtensionDecl *LastExtension = nullptr; /// \brief The generation at which we last loaded extensions. unsigned ExtensionGeneration = 0; /// \brief A lookup table containing all of the members of this type and /// its extensions. /// /// The table itself is lazily constructed and updated when lookupDirect() is /// called. MemberLookupTable *LookupTable = nullptr; friend class MemberLookupTable; friend class ExtensionDecl; protected: Type DeclaredTy; Type DeclaredTyInContext; void setDeclaredType(Type declaredTy) { assert(DeclaredTy.isNull() && "Already set declared type"); DeclaredTy = declaredTy; } NominalTypeDecl(DeclKind K, DeclContext *DC, Identifier name, SourceLoc NameLoc, MutableArrayRef inherited, GenericParamList *GenericParams) : TypeDecl(K, DC, name, NameLoc, inherited), DeclContext(DeclContextKind::NominalTypeDecl, DC), GenericParams(GenericParams), DeclaredTy(nullptr) {} friend class ProtocolType; public: using TypeDecl::getASTContext; ArrayRef getMembers() const { return Members; } SourceRange getBraces() const { return Braces; } void setMembers(ArrayRef M, SourceRange B); GenericParamList *getGenericParams() const { return GenericParams; } /// Provide the set of parameters to a generic type, or null if /// this function is not generic. void setGenericParams(GenericParamList *params) { assert(!GenericParams && "Already has generic parameters"); GenericParams = params; } /// Set the generic signature of this type. void setGenericSignature(ArrayRef params, ArrayRef requirements); /// Retrieve the generic parameter types. ArrayRef getGenericParamTypes() const { if (!GenericSig) return { }; return GenericSig->getGenericParams(); } /// Retrieve the generic requirements. ArrayRef getGenericRequirements() const { if (!GenericSig) return { }; return GenericSig->getRequirements(); } /// getDeclaredType - Retrieve the type declared by this entity. Type getDeclaredType() const { return DeclaredTy; } /// Compute the type (and declared type) of this nominal type. void computeType(); Type getDeclaredTypeInContext(); /// Get the "interface" type of the given nominal type, which is the /// type used to refer to the nominal type externally. /// /// For a generic type, or a member thereof, this is the a specialization /// of the type using its own generic parameters. Type computeInterfaceType() const; /// \brief Add a new extension to this nominal type. void addExtension(ExtensionDecl *extension); /// \brief Retrieve the set of extensions of this type. ExtensionRange getExtensions(); /// Find all of the declarations with the given name within this nominal type /// and its extensions. /// /// This routine does not look into superclasses, nor does it consider /// protocols to which the nominal type conforms. Furthermore, the resulting /// set of declarations has not been filtered for visibility, nor have /// overridden declarations been removed. ArrayRef lookupDirect(Identifier name); /// Collect the set of protocols to which this type should implicitly /// conform, such as DynamicLookup (for classes). void getImplicitProtocols(SmallVectorImpl &protocols); private: /// Predicate used to filter StoredPropertyRange. static bool isStoredProperty(VarDecl *vd); // at end of file public: /// A range for iterating the stored member variables of a structure. using StoredPropertyRange = DeclFilterRange; /// Return a collection of the stored member variables of this type. StoredPropertyRange getStoredProperties() const { return StoredPropertyRange(getMembers()); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= DeclKind::First_NominalTypeDecl && D->getKind() <= DeclKind::Last_NominalTypeDecl; } static bool classof(const DeclContext *C) { return C->getContextKind() == DeclContextKind::NominalTypeDecl; } static bool classof(const NominalTypeDecl *D) { return true; } static bool classof(const ExtensionDecl *D) { return false; } using DeclContext::operator new; }; /// \brief This is the declaration of an enum. /// /// For example: /// /// \code /// enum Bool { /// case false /// case true /// } /// /// enum Optional { /// case None /// case Just(T) /// } /// \endcode /// /// The type of the decl itself is a MetaTypeType; use getDeclaredType() /// to get the declared type ("Bool" or "Optional" in the above example). class EnumDecl : public NominalTypeDecl { SourceLoc EnumLoc; Type RawType; public: EnumDecl(SourceLoc EnumLoc, Identifier Name, SourceLoc NameLoc, MutableArrayRef Inherited, GenericParamList *GenericParams, DeclContext *DC); SourceLoc getStartLoc() const { return EnumLoc; } SourceRange getSourceRange() const { return SourceRange(EnumLoc, getBraces().End); } EnumElementDecl *getElement(Identifier Name) const; private: /// Predicate used to filter ElementRange. static bool isElement(EnumElementDecl *ued) { return true; } public: /// A range for iterating the elements of an enum. using ElementRange = DeclFilterRange; /// Return a range that iterates over all the elements of an enum. ElementRange getAllElements() const { return ElementRange(getMembers()); } /// Insert all of the 'case' element declarations into a DenseSet. void getAllElements(llvm::DenseSet &elements) const { for (auto elt : getAllElements()) elements.insert(elt); } /// Retrieve the status of circularity checking for class inheritance. CircularityCheck getCircularityCheck() const { return static_cast(EnumDeclBits.Circularity); } /// Record the current stage of circularity checking. void setCircularityCheck(CircularityCheck circularity) { EnumDeclBits.Circularity = static_cast(circularity); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == DeclKind::Enum; } static bool classof(const NominalTypeDecl *D) { return D->getKind() == DeclKind::Enum; } static bool classof(const DeclContext *C) { return isa(C) && classof(cast(C)); } /// Determine whether this enum declares a raw type in its inheritance clause. bool hasRawType() const { return (bool)RawType; } /// Retrieve the declared raw type of the enum from its inheritance clause, /// or null if it has none. Type getRawType() const { return RawType; } /// Set the raw type of the enum from its inheritance clause. void setRawType(Type rawType) { RawType = rawType; } }; /// StructDecl - This is the declaration of a struct, for example: /// /// struct Complex { var R : Double, I : Double } /// /// The type of the decl itself is a MetaTypeType; use getDeclaredType() /// to get the declared type ("Complex" in the above example). class StructDecl : public NominalTypeDecl { SourceLoc StructLoc; public: StructDecl(SourceLoc StructLoc, Identifier Name, SourceLoc NameLoc, MutableArrayRef Inherited, GenericParamList *GenericParams, DeclContext *DC); SourceLoc getStartLoc() const { return StructLoc; } SourceRange getSourceRange() const { return SourceRange(StructLoc, getBraces().End); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == DeclKind::Struct; } static bool classof(const NominalTypeDecl *D) { return D->getKind() == DeclKind::Struct; } static bool classof(const DeclContext *C) { return isa(C) && classof(cast(C)); } }; /// ClassDecl - This is the declaration of a class, for example: /// /// class Complex { var R : Double, I : Double } /// /// The type of the decl itself is a MetaTypeType; use getDeclaredType() /// to get the declared type ("Complex" in the above example). class ClassDecl : public NominalTypeDecl { SourceLoc ClassLoc; Type Superclass; public: ClassDecl(SourceLoc ClassLoc, Identifier Name, SourceLoc NameLoc, MutableArrayRef Inherited, GenericParamList *GenericParams, DeclContext *DC); SourceLoc getStartLoc() const { return ClassLoc; } SourceRange getSourceRange() const { return SourceRange(ClassLoc, getBraces().End); } /// Determine whether this class has a superclass. bool hasSuperclass() const { return (bool)Superclass; } /// Retrieve the superclass of this class, or null if there is no superclass. Type getSuperclass() const { return Superclass; } /// Set the superclass of this class. void setSuperclass(Type superclass) { Superclass = superclass; } /// Retrieve the status of circularity checking for class inheritance. CircularityCheck getCircularityCheck() const { return static_cast(ClassDeclBits.Circularity); } /// Record the current stage of circularity checking. void setCircularityCheck(CircularityCheck circularity) { ClassDeclBits.Circularity = static_cast(circularity); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == DeclKind::Class; } static bool classof(const NominalTypeDecl *D) { return D->getKind() == DeclKind::Class; } static bool classof(const DeclContext *C) { return isa(C) && classof(cast(C)); } }; /// ProtocolDecl - A declaration of a protocol, for example: /// /// protocol Drawable { /// func draw() /// } class ProtocolDecl : public NominalTypeDecl { SourceLoc ProtocolLoc; bool requiresClassSlow(); public: ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc, SourceLoc NameLoc, Identifier Name, MutableArrayRef Inherited); using Decl::getASTContext; void setMembers(MutableArrayRef M, SourceRange B) { NominalTypeDecl::setMembers(M, B); } /// \brief Determine whether this protocol inherits from the given ("super") /// protocol. bool inheritsFrom(const ProtocolDecl *Super) const; /// \brief Collect all of the inherited protocols into the given set. void collectInherited(llvm::SmallPtrSet &Inherited); ProtocolType *getDeclaredType() const { return reinterpret_cast(DeclaredTy.getPointer()); } SourceLoc getStartLoc() const { return ProtocolLoc; } SourceRange getSourceRange() const { return SourceRange(ProtocolLoc, getBraces().End); } /// \brief Retrieve the generic parameter 'Self'. GenericTypeParamDecl *getSelf() const; /// True if this protocol can only be conformed to by class types. bool requiresClass() { if (ProtocolDeclBits.RequiresClassValid) return ProtocolDeclBits.RequiresClass; return requiresClassSlow(); } /// Determine whether an existential value conforming to just this protocol /// conforms to the protocol itself. /// /// \returns an empty optional if not yet known, true if the existential /// does conform to this protocol, and false otherwise. Optional existentialConformsToSelf() const { if (ProtocolDeclBits.ExistentialConformsToSelfValid) return ProtocolDeclBits.ExistentialConformsToSelf; return Nothing; } /// Set whether the existential of this protocol type conforms to this /// protocol. void setExistentialConformsToSelf(bool conforms) { ProtocolDeclBits.ExistentialConformsToSelfValid = true; ProtocolDeclBits.ExistentialConformsToSelf = conforms; } /// If this is known to be a compiler-known protocol, returns the kind. /// Otherwise returns Nothing. /// /// Note that this is only valid after type-checking. Optional getKnownProtocolKind() const { if (ProtocolDeclBits.KnownProtocol == 0) return Nothing; return static_cast(ProtocolDeclBits.KnownProtocol - 1); } /// Check whether this protocol is of a specific, known protocol kind. bool isSpecificProtocol(KnownProtocolKind kind) const { if (auto knownKind = getKnownProtocolKind()) return *knownKind == kind; return false; } /// Records that this is a compiler-known protocol. void setKnownProtocolKind(KnownProtocolKind kind) { assert((!getKnownProtocolKind() || *getKnownProtocolKind() == kind) && "can't reset known protocol kind"); ProtocolDeclBits.KnownProtocol = static_cast(kind) + 1; assert(getKnownProtocolKind() && *getKnownProtocolKind() == kind && "not enough bits"); } /// Retrieve the status of circularity checking for protocol inheritance. CircularityCheck getCircularityCheck() const { return static_cast(ProtocolDeclBits.Circularity); } /// Record the current stage of circularity checking. void setCircularityCheck(CircularityCheck circularity) { ProtocolDeclBits.Circularity = static_cast(circularity); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == DeclKind::Protocol; } static bool classof(const NominalTypeDecl *D) { return D->getKind() == DeclKind::Protocol; } static bool classof(const DeclContext *C) { return isa(C) && classof(cast(C)); } }; /// VarDecl - 'var' declaration. class VarDecl : public ValueDecl { private: struct GetSetRecord { SourceRange Braces; FuncDecl *Get; // User-defined getter FuncDecl *Set; // User-defined setter }; // FIXME: These fields are useless for most of the VarDecls that are created // for patterns. We should refactor to a new node. GetSetRecord *GetSet = nullptr; PatternBindingDecl *ParentPattern = nullptr; VarDecl *OverriddenDecl = nullptr; public: VarDecl(bool IsStatic, SourceLoc NameLoc, Identifier Name, Type Ty, DeclContext *DC) : ValueDecl(DeclKind::Var, DC, Name, NameLoc) { VarDeclBits.Static = IsStatic; setType(Ty); } SourceLoc getStartLoc() const { return getNameLoc(); } SourceRange getSourceRange() const { return getNameLoc(); } /// \brief Retrieve the source range of the variable type. /// /// Only for use in diagnostics. It is not always possible to always /// precisely point to the variable type because of type aliases. SourceRange getTypeSourceRangeForDiagnostics() const; /// \brief Determine whether this variable is computed, which means it /// has no storage but does have a user-defined getter or setter. /// /// The opposite of "computed" is "stored". bool isComputed() const { return GetSet != nullptr; } /// \brief Turn this into a computed variable, providing a getter and setter. void setComputedAccessors(ASTContext &Context, SourceLoc LBraceLoc, FuncDecl *Get, FuncDecl *Set, SourceLoc RBraceLoc); /// \brief Retrieve the getter used to access the value of this variable. FuncDecl *getGetter() const { return GetSet? GetSet->Get : nullptr; } /// \brief Retrieve the setter used to mutate the value of this variable. FuncDecl *getSetter() const { return GetSet? GetSet->Set : nullptr; } /// Retrieve the type of the getter. Type getGetterType() const; /// Retrieve the type of the setter. Type getSetterType() const; /// \brief Returns whether the var is settable, either because it is a /// stored var or because it has a custom setter. bool isSettable() const { return !GetSet || GetSet->Set; } VarDecl *getOverriddenDecl() const { return OverriddenDecl; } void setOverriddenDecl(VarDecl *over) { OverriddenDecl = over; } PatternBindingDecl *getParentPattern() const { return ParentPattern; } void setParentPattern(PatternBindingDecl *PBD) { ParentPattern = PBD; } /// Determine whether this declaration is an anonymous closure parameter. bool isAnonClosureParam() const; /// Given that this is an Objective-C property declaration, produce /// its getter selector in the given buffer (as UTF-8). StringRef getObjCGetterSelector(SmallVectorImpl &buffer) const; /// Given that this is an Objective-C property declaration, produce /// its setter selector in the given buffer (as UTF-8). StringRef getObjCSetterSelector(SmallVectorImpl &buffer) const; /// Is this a type ('static') variable? bool isStatic() const { return VarDeclBits.Static; } void setStatic(bool IsStatic) { VarDeclBits.Static = IsStatic; } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == DeclKind::Var; } }; /// \brief Base class for function-like declarations. class AbstractFunctionDecl : public ValueDecl, public DeclContext { public: enum class BodyKind { /// The function did not have a body in the source code file. None, /// Function body is delayed, to be parsed later. Unparsed, /// Function body is parsed and available as an AST subtree. Parsed, /// Function body is not available, although it was written in the source. Skipped }; BodyKind getBodyKind() const { return BodyKind(AbstractFunctionDeclBits.BodyKind); } protected: // If a function has a body at all, we have either a parsed body AST node or // we have saved the end location of the unparsed body. union { /// This enum member is active if getBodyKind() == BodyKind::Parsed. BraceStmt *Body; /// End location of the function body when the body is delayed or skipped. /// This enum member is active if getBodyKind() is BodyKind::Unparsed or /// BodyKind::Skipped. SourceLoc BodyEndLoc; }; /// Pointer to the implicit 'self' decl and a bit that is set to true when /// this pointer is computed already. mutable llvm::PointerIntPair ImplicitSelfDeclAndIsCached; GenericParamList *GenericParams; CaptureInfo Captures; AbstractFunctionDecl(DeclKind Kind, DeclContext *Parent, Identifier Name, SourceLoc NameLoc, VarDecl *ImplicitSelfDecl, GenericParamList *GenericParams) : ValueDecl(Kind, Parent, Name, NameLoc), DeclContext(DeclContextKind::AbstractFunctionDecl, Parent), Body(nullptr), GenericParams(GenericParams) { if (ImplicitSelfDecl) ImplicitSelfDeclAndIsCached.setPointerAndInt(ImplicitSelfDecl, true); else ImplicitSelfDeclAndIsCached.setPointerAndInt(nullptr, false); setBodyKind(BodyKind::None); AbstractFunctionDeclBits.HasSelectorStyleSignature = false; } VarDecl *getImplicitSelfDeclSlow() const; MutableArrayRef getArgParamBuffer(); MutableArrayRef getBodyParamBuffer(); void setBodyKind(BodyKind K) { AbstractFunctionDeclBits.BodyKind = unsigned(K); } public: /// \brief If this is a method in a type extension for some type, /// return that type, otherwise return Type(). Type getExtensionType() const; /// Returns true if the function has a body written in the source file. /// /// Note that a true return value does not imply that the body was actually /// parsed. bool hasBody() const { return getBodyKind() != BodyKind::None; } /// Returns the function body, if it was parsed, or nullptr otherwise. /// /// Note that a null return value does not imply that the source code did not /// have a body for this function. /// /// \sa hasBody() BraceStmt *getBody() const { if (getBodyKind() == BodyKind::Parsed) return Body; return nullptr; } void setBody(BraceStmt *S) { assert(getBodyKind() != BodyKind::Skipped && "can not set a body if it was skipped"); Body = S; setBodyKind(BodyKind::Parsed); } /// \brief Note that the body was skipped for this function. Function body /// can not be attached after this call. void setBodySkipped(SourceLoc EndLoc) { assert(getBodyKind() == BodyKind::None); BodyEndLoc = EndLoc; setBodyKind(BodyKind::Skipped); } /// \brief Note that parsing for the body was delayed. void setBodyDelayed(SourceLoc EndLoc) { assert(getBodyKind() == BodyKind::None); BodyEndLoc = EndLoc; setBodyKind(BodyKind::Unparsed); } CaptureInfo &getCaptureInfo() { return Captures; } const CaptureInfo &getCaptureInfo() const { return Captures; } bool hasSelectorStyleSignature() const { return AbstractFunctionDeclBits.HasSelectorStyleSignature; } void setHasSelectorStyleSignature() { AbstractFunctionDeclBits.HasSelectorStyleSignature = true; } /// Determine the default argument kind and type for the given argument index /// in this declaration, which must be a function or constructor. /// /// \param Index The index of the argument for which we are querying the /// default argument. /// /// \returns the default argument kind and, if there is a default argument, /// the type of the corresponding parameter. std::pair getDefaultArg(unsigned Index) const; /// \brief Returns the argument pattern(s) for the function definition /// that determine the function type. // /// - For a definition of the form `func foo(a:A, b:B)`, this will /// be a one-element array containing the argument pattern `(a:A, b:B)`. /// - For a curried definition such as `func foo(a:A)(b:B)`, this will /// be a multiple-element array containing a pattern for each level /// of currying, in this case two patterns `(a:A)` and `(b:B)`. /// - For a selector-style definition such as `func foo(a:A) bar(b:B)`, /// this will be a one-element array containing the argument pattern /// of the keyword arguments, in this case `(_:A, bar:B)`. For selector- /// style definitions, this is different from `getBodyParamPatterns`, /// which would return the declared parameter names `(a:A, b:B)`. /// /// If the function expression refers to a method definition, there will /// be an additional first argument pattern for the `this` parameter. MutableArrayRef getArgParamPatterns() { return getArgParamBuffer(); } ArrayRef getArgParamPatterns() const { auto Patterns = const_cast(this)->getArgParamBuffer(); return ArrayRef(Patterns.data(), Patterns.size()); } /// \brief Returns the parameter pattern(s) for the function definition that /// determine the parameter names bound in the function body. /// /// Typically, this is the same as \c getArgParamPatterns, unless the /// function was defined with selector-style syntax such as: /// \code /// func foo(a:A) bar(b:B) {} /// \endcode /// /// For a selector-style definition, \c getArgParamPatterns will return the /// pattern that describes the keyword argument names, in this case /// `(_:A, bar:B)`, whereas \c getBodyParamPatterns will return a pattern /// referencing the declared parameter names in the function body's scope, /// in this case `(a:A, b:B)`. /// /// In all cases `getArgParamPatterns().size()` should equal /// `getBodyParamPatterns().size()`, and the corresponding elements of each /// tuple type should have equivalent types. MutableArrayRef getBodyParamPatterns() { return getBodyParamBuffer(); } ArrayRef getBodyParamPatterns() const { auto Patterns = const_cast(this)->getBodyParamBuffer(); return ArrayRef(Patterns.data(), Patterns.size()); } /// \brief If this is a method in a type or extension thereof, compute /// and return the type to be used for the 'self' argument of the type, or an /// empty Type() if no 'self' argument should exist. This can /// only be used after name binding has resolved types. /// /// \param outerGenericParams If non-NULL, and this function is an instance /// of a generic type, will be set to the generic parameter list of that /// generic type. Type computeSelfType(GenericParamList **outerGenericParams = nullptr); /// \brief This method returns the implicit 'self' decl. /// /// Note that some functions don't have an implicit 'self' decl, for example, /// free functions. In this case nullptr is returned. VarDecl *getImplicitSelfDecl() const { if (ImplicitSelfDeclAndIsCached.getInt()) return ImplicitSelfDeclAndIsCached.getPointer(); return getImplicitSelfDeclSlow(); } /// \brief Retrieve the set of parameters to a generic function, or null if /// this function is not generic. GenericParamList *getGenericParams() const { return GenericParams; } /// \brief Determine whether this is a generic function, which can only be /// used when each of the archetypes is bound to a particular concrete type. bool isGeneric() const { return GenericParams != nullptr; } static bool classof(const Decl *D) { return D->getKind() >= DeclKind::First_AbstractFunctionDecl && D->getKind() <= DeclKind::Last_AbstractFunctionDecl; } static bool classof(const DeclContext *DC) { return DC->getContextKind() == DeclContextKind::AbstractFunctionDecl; } using DeclContext::operator new; using Decl::getASTContext; }; class OperatorDecl; /// FuncDecl - 'func' declaration. class FuncDecl : public AbstractFunctionDecl { friend class AbstractFunctionDecl; SourceLoc StaticLoc; // Location of the 'static' token or invalid. SourceLoc FuncLoc; // Location of the 'func' token. TypeLoc FnRetType; /// The result type as seen from the body of the function. /// /// \sa getBodyResultType() Type BodyResultType; llvm::PointerIntPair GetOrSetDecl; FuncDecl *OverriddenDecl; OperatorDecl *Operator; FuncDecl(SourceLoc StaticLoc, SourceLoc FuncLoc, Identifier Name, SourceLoc NameLoc, unsigned NumParamPatterns, GenericParamList *GenericParams, Type Ty, DeclContext *Parent) : AbstractFunctionDecl(DeclKind::Func, Parent, Name, NameLoc, nullptr, GenericParams), StaticLoc(StaticLoc), FuncLoc(FuncLoc), OverriddenDecl(nullptr), Operator(nullptr) { FuncDeclBits.Static = StaticLoc.isValid() || getName().isOperator(); assert(NumParamPatterns > 0); FuncDeclBits.NumParamPatterns = NumParamPatterns; setType(Ty); } VarDecl *getImplicitSelfDeclImpl() const; unsigned getNumParamPatternsImpl() const { return FuncDeclBits.NumParamPatterns; } public: /// Factory function only for use by deserialization. static FuncDecl *createDeserialized(ASTContext &Context, SourceLoc StaticLoc, SourceLoc FuncLoc, Identifier Name, SourceLoc NameLoc, GenericParamList *GenericParams, Type Ty, unsigned NumParamPatterns, DeclContext *Parent); static FuncDecl *create(ASTContext &Context, SourceLoc StaticLoc, SourceLoc FuncLoc, Identifier Name, SourceLoc NameLoc, GenericParamList *GenericParams, Type Ty, ArrayRef ArgParams, ArrayRef BodyParams, TypeLoc FnRetType, DeclContext *Parent); bool isStatic() const { return FuncDeclBits.Static; } void setStatic(bool Static = true) { FuncDeclBits.Static = Static; } void setDeserializedSignature(ArrayRef ArgParams, ArrayRef BodyParams, TypeLoc FnRetType); /// \brief Returns the "natural" number of argument clauses taken by this /// function. This value is always at least one, and it may be more if the /// function is implicitly or explicitly curried. /// /// For example, this function: /// \code /// func negate(x : Int) -> Int { return -x } /// \endcode /// has a natural argument count of 1 if it is freestanding. If it is /// a method, it has a natural argument count of 2, as does this /// curried function: /// \code /// func add(x : Int)(y : Int) -> Int { return x + y } /// \endcode /// /// This value never exceeds the number of chained function types /// in the function's type, but it can be less for functions which /// return a value of function type: /// \code /// func const(x : Int) -> () -> Int { return { x } } // NAC==1 /// \endcode unsigned getNaturalArgumentCount() const { return getNumParamPatternsImpl(); } SourceLoc getStaticLoc() const { return StaticLoc; } SourceLoc getFuncLoc() const { return FuncLoc; } SourceLoc getStartLoc() const { return StaticLoc.isValid() ? StaticLoc : FuncLoc; } SourceRange getSourceRange() const; TypeLoc &getBodyResultTypeLoc() { return FnRetType; } const TypeLoc &getBodyResultTypeLoc() const { return FnRetType; } /// Retrieve the result type of this function. /// /// \sa getBodyResultType Type getResultType() const; /// Retrieve the result type of this function for use within the function /// definition. /// /// FIXME: The statement below is a wish, not reality. /// The "body" result type will only differ from the result type within the /// interface to the function for a polymorphic function, where the interface /// may contain generic parameters while the definition will contain /// the corresponding archetypes. Type getBodyResultType() const { return BodyResultType; } /// Set the result type as viewed from the function body. /// /// \sa getBodyResultType void setBodyResultType(Type bodyResultType) { assert(BodyResultType.isNull() && "Already set body result type"); BodyResultType = bodyResultType; } /// Revert to an empty type. void revertType() { BodyResultType = Type(); overwriteType(Type()); } /// isUnaryOperator - Determine whether this is a unary operator /// implementation, in other words, the name of the function is an operator, /// and the argument list consists syntactically of a single-element tuple /// pattern. This check is syntactic rather than type-based in order to allow /// for the definition of unary operators on tuples, as in: /// func [prefix] + (_:(a:Int, b:Int)) /// This also allows the unary-operator-ness of a func decl to be determined /// prior to type checking. bool isUnaryOperator() const; /// isBinaryOperator - Determine whether this is a binary operator /// implementation, in other words, the name of the function is an operator, /// and the argument list consists syntactically of a two-element tuple /// pattern. This check is syntactic rather than type-based in order to /// distinguish a binary operator from a unary operator on tuples, as in: /// func [prefix] + (_:(a:Int, b:Int)) // unary operator +(1,2) /// func [infix] + (a:Int, b:Int) // binary operator 1 + 2 /// This also allows the binary-operator-ness of a func decl to be determined /// prior to type checking. bool isBinaryOperator() const; /// makeGetter - Note that this function is the getter for the given /// declaration, which may be either a variable or a subscript declaration. void makeGetter(ValueDecl *D) { GetOrSetDecl.setPointer(D); GetOrSetDecl.setInt(false); } /// makeSetter - Note that this function is the setter for the given /// declaration, which may be either a variable or a subscript declaration. void makeSetter(ValueDecl *D) { GetOrSetDecl.setPointer(D); GetOrSetDecl.setInt(true); } /// getGetterDecl - If this function is a getter, retrieve the declaration for /// which it is a getter. Otherwise, returns null. ValueDecl *getGetterDecl() const { return GetOrSetDecl.getInt()? nullptr : GetOrSetDecl.getPointer(); } /// getSetterDecl - If this function is a setter, retrieve the declaration for /// which it is a setter. Otherwise, returns null. ValueDecl *getSetterDecl() const { return GetOrSetDecl.getInt()? GetOrSetDecl.getPointer() : nullptr; } /// isGetterOrSetter - Determine whether this is a getter or a setter vs. /// a normal function. bool isGetterOrSetter() const { return getGetterOrSetterDecl() != 0; } /// getGetterOrSetterDecl - Return the declaration for which this function /// is a getter or setter, if it is one. ValueDecl *getGetterOrSetterDecl() const { return GetOrSetDecl.getPointer(); } /// Given that this is an Objective-C method declaration, produce /// its selector in the given buffer (as UTF-8). StringRef getObjCSelector(SmallVectorImpl &buffer) const; FuncDecl *getOverriddenDecl() const { return OverriddenDecl; } void setOverriddenDecl(FuncDecl *over) { OverriddenDecl = over; } OperatorDecl *getOperatorDecl() const { return Operator; } void setOperatorDecl(OperatorDecl *o) { assert(isOperator() && "can't set an OperatorDecl for a non-operator"); Operator = o; } static bool classof(const Decl *D) { return D->getKind() == DeclKind::Func; } }; /// \brief This represents a 'case' declaration in an 'enum', which may declare /// one or more individual comma-separated EnumElementDecls. class EnumCaseDecl : public Decl { SourceLoc CaseLoc; /// The number of tail-allocated element pointers. unsigned NumElements; EnumCaseDecl(SourceLoc CaseLoc, ArrayRef Elements, DeclContext *DC) : Decl(DeclKind::EnumCase, DC), CaseLoc(CaseLoc), NumElements(Elements.size()) { memcpy(this + 1, Elements.begin(), NumElements * sizeof(EnumElementDecl*)); } EnumElementDecl * const *getElementsBuf() const { return reinterpret_cast(this + 1); } public: static EnumCaseDecl *create(SourceLoc CaseLoc, ArrayRef Elements, DeclContext *DC); /// Get the list of elements declared in this case. ArrayRef getElements() const { return {getElementsBuf(), NumElements}; } SourceLoc getLoc() const { return CaseLoc; } SourceRange getSourceRange() const; static bool classof(const Decl *D) { return D->getKind() == DeclKind::EnumCase; } }; /// \brief This represents a single case of an 'enum' declaration. /// /// For example, the X, Y, and Z in this enum: /// /// \code /// enum V { /// case X(Int), Y(Int) /// case Z /// } /// \endcode /// /// The type of an EnumElementDecl is always the EnumType for the containing /// enum. EnumElementDecls are represented in the AST as members of their /// parent EnumDecl, although syntactically they are subordinate to the /// EnumCaseDecl. class EnumElementDecl : public ValueDecl { /// This is the type specified with the enum element, for /// example 'Int' in 'case Y(Int)'. This is null if there is no type /// associated with this element, as in 'case Z' or in all elements of enum /// definitions. TypeLoc ArgumentType; SourceLoc EqualsLoc; /// The raw value literal for the enum element, or null. LiteralExpr *RawValueExpr; /// The type-checked raw value expression. Expr *TypeCheckedRawValueExpr = nullptr; public: EnumElementDecl(SourceLoc IdentifierLoc, Identifier Name, TypeLoc ArgumentType, SourceLoc EqualsLoc, LiteralExpr *RawValueExpr, DeclContext *DC) : ValueDecl(DeclKind::EnumElement, DC, Name, IdentifierLoc), ArgumentType(ArgumentType), EqualsLoc(EqualsLoc), RawValueExpr(RawValueExpr) {} bool hasArgumentType() const { return !ArgumentType.getType().isNull(); } Type getArgumentType() const { return ArgumentType.getType(); } TypeLoc &getArgumentTypeLoc() { return ArgumentType; } bool hasRawValueExpr() const { return RawValueExpr; } LiteralExpr *getRawValueExpr() const { return RawValueExpr; } void setRawValueExpr(LiteralExpr *e) { RawValueExpr = e; } Expr *getTypeCheckedRawValueExpr() const { return TypeCheckedRawValueExpr; } void setTypeCheckedRawValueExpr(Expr *e) { TypeCheckedRawValueExpr = e; } /// Return the containing EnumDecl. EnumDecl *getParentEnum() const { return cast(getDeclContext()); } SourceLoc getStartLoc() const { return getNameLoc(); } SourceRange getSourceRange() const; static bool classof(const Decl *D) { return D->getKind() == DeclKind::EnumElement; } }; inline SourceRange EnumCaseDecl::getSourceRange() const { auto subRange = getElements().back()->getSourceRange(); if (subRange.isValid()) return {CaseLoc, subRange.End}; return {}; } /// Describes the kind of subscripting used in Objective-C. enum class ObjCSubscriptKind { /// Not an Objective-C subscripting kind. None, /// Objective-C indexed subscripting, which is based on an integral /// index. Indexed, /// Objective-C keyed subscripting, which is based on an object /// argument or metatype thereof. Keyed }; /// \brief Declares a subscripting operator for a type. /// /// A subscript declaration is defined as a get/set pair that produces a /// specific type. For example: /// /// \code /// subscript (i : Int) -> String { /// get: /* return ith String */ /// set: /* set ith string to value */ /// } /// \endcode /// /// A type with a subscript declaration can be used as the base of a subscript /// expression a[i], where a is of the subscriptable type and i is the type /// of the index. A subscript can have multiple indices: /// /// \code /// struct Matrix { /// subscript (i : Int, j : Int) -> Double { /// get: /* return element at position (i, j) */ /// set: /* set element at position (i, j) */ /// } /// } /// \endcode /// /// A given type can have multiple subscript declarations, so long as the /// signatures (indices and element type) are distinct. /// /// FIXME: SubscriptDecl isn't naturally a ValueDecl, but it's currently useful /// to get name lookup to find it with a bogus name. class SubscriptDecl : public ValueDecl { SourceLoc ArrowLoc; Pattern *Indices; TypeLoc ElementTy; SourceRange Braces; FuncDecl *Get; FuncDecl *Set; SubscriptDecl *OverriddenDecl; public: SubscriptDecl(Identifier NameHack, SourceLoc SubscriptLoc, Pattern *Indices, SourceLoc ArrowLoc, TypeLoc ElementTy, SourceRange Braces, FuncDecl *Get, FuncDecl *Set, DeclContext *Parent) : ValueDecl(DeclKind::Subscript, Parent, NameHack, SubscriptLoc), ArrowLoc(ArrowLoc), Indices(Indices), ElementTy(ElementTy), Braces(Braces), Get(Get), Set(Set), OverriddenDecl(nullptr) { } SourceLoc getSubscriptLoc() const { return getNameLoc(); } SourceLoc getStartLoc() const { return getSubscriptLoc(); } SourceRange getSourceRange() const; /// \brief Retrieve the indices for this subscript operation. Pattern *getIndices() { return Indices; } const Pattern *getIndices() const { return Indices; } void setIndices(Pattern *p) { Indices = p; } /// \brief Retrieve the type of the element referenced by a subscript /// operation. Type getElementType() const { return ElementTy.getType(); } TypeLoc &getElementTypeLoc() { return ElementTy; } /// \brief Retrieve the subscript getter, a function that takes the indices /// and produces a value of the element type. FuncDecl *getGetter() const { return Get; } /// \brief Retrieve the subscript setter, a function that takes the indices /// and a new value of the lement type and updates the corresponding value. /// /// The subscript setter is optional. FuncDecl *getSetter() const { return Set; } /// \brief Returns whether the subscript operation has a setter. bool isSettable() const { return Set; } /// Retrieve the type of the getter. Type getGetterType() const; /// Retrieve the type of the setter. Type getSetterType() const; /// Determine the kind of Objective-C subscripting this declaration /// implies. ObjCSubscriptKind getObjCSubscriptKind() const; /// Given that this is an Objective-C subscript declaration, produce /// its getter selector. StringRef getObjCGetterSelector() const; /// Given that this is an Objective-C subscript declaration, produce /// its setter selector. StringRef getObjCSetterSelector() const; SubscriptDecl *getOverriddenDecl() const { return OverriddenDecl; } void setOverriddenDecl(SubscriptDecl *over) { OverriddenDecl = over; } static bool classof(const Decl *D) { return D->getKind() == DeclKind::Subscript; } }; /// ConstructorDecl - Declares a constructor for a type. For example: /// /// \code /// struct X { /// var x : Int /// constructor(i : Int) { /// x = i /// } /// } /// \endcode class ConstructorDecl : public AbstractFunctionDecl { friend class AbstractFunctionDecl; Pattern *ArgParams; Pattern *BodyParams; /// The type of the initializing constructor. Type InitializerType; /// The interface type of the initializing constructor. Type InitializerInterfaceType; public: ConstructorDecl(Identifier NameHack, SourceLoc ConstructorLoc, Pattern *ArgParams, Pattern *BodyParams, VarDecl *ImplicitSelfDecl, GenericParamList *GenericParams, DeclContext *Parent) : AbstractFunctionDecl(DeclKind::Constructor, Parent, NameHack, ConstructorLoc, ImplicitSelfDecl, GenericParams), ArgParams(ArgParams), BodyParams(BodyParams) { assert(ImplicitSelfDecl && "constructors should have a non-null self"); } SourceLoc getConstructorLoc() const { return getNameLoc(); } SourceLoc getStartLoc() const { return getConstructorLoc(); } SourceRange getSourceRange() const; Pattern *getArgParams() { return ArgParams; } const Pattern *getArgParams() const { return ArgParams; } void setArgParams(Pattern *argParams) { ArgParams = argParams; } Pattern *getBodyParams() { return BodyParams; } const Pattern *getBodyParams() const { return BodyParams; } void setBodyParams(Pattern *bodyParams) { BodyParams = bodyParams; } /// getArgumentType - get the type of the argument tuple Type getArgumentType() const; /// \brief Get the type of the constructed object. Type getResultType() const; /// Given that this is an Objective-C method declaration, produce /// its selector in the given buffer (as UTF-8). StringRef getObjCSelector(SmallVectorImpl &buffer) const; /// Get the type of the initializing constructor. Type getInitializerType() const { return InitializerType; } void setInitializerType(Type t) { InitializerType = t; } /// Get the interface type of the initializing constructor. Type getInitializerInterfaceType() const { return InitializerInterfaceType; } void setInitializerInterfaceType(Type t) { InitializerInterfaceType = t; } static bool classof(const Decl *D) { return D->getKind() == DeclKind::Constructor; } }; /// DestructorDecl - Declares a destructor for a type. For example: /// /// \code /// struct X { /// var fd : Int /// destructor() { /// close(fd) /// } /// } /// \endcode class DestructorDecl : public AbstractFunctionDecl { public: DestructorDecl(Identifier NameHack, SourceLoc DestructorLoc, VarDecl *ImplicitSelfDecl, DeclContext *Parent) : AbstractFunctionDecl(DeclKind::Destructor, Parent, NameHack, DestructorLoc, ImplicitSelfDecl, nullptr) { assert(ImplicitSelfDecl && "destructors should have a non-null self"); } SourceLoc getDestructorLoc() const { return getNameLoc(); } SourceLoc getStartLoc() const { return getDestructorLoc(); } SourceRange getSourceRange() const; static bool classof(const Decl *D) { return D->getKind() == DeclKind::Destructor; } }; /// Abstract base class of operator declarations. class OperatorDecl : public Decl { SourceLoc OperatorLoc, NameLoc, LBraceLoc, RBraceLoc; Identifier name; public: OperatorDecl(DeclKind kind, DeclContext *DC, SourceLoc OperatorLoc, Identifier Name, SourceLoc NameLoc, SourceLoc LBraceLoc, SourceLoc RBraceLoc) : Decl(kind, DC), OperatorLoc(OperatorLoc), NameLoc(NameLoc), LBraceLoc(LBraceLoc), RBraceLoc(RBraceLoc), name(Name) {} SourceLoc getLoc() const { return NameLoc; } SourceRange getSourceRange() const { return {OperatorLoc, RBraceLoc}; } SourceLoc getOperatorLoc() const { return OperatorLoc; } SourceLoc getLBraceLoc() const { return LBraceLoc; } SourceLoc getRBraceLoc() const { return RBraceLoc; } Identifier getName() const { return name; } static bool classof(const Decl *D) { return D->getKind() >= DeclKind::First_OperatorDecl && D->getKind() <= DeclKind::Last_OperatorDecl; } }; /// Declares the behavior of an infix operator. For example: /// /// \code /// operator infix /+/ { /// associativity left /// precedence 123 /// } /// \endcode class InfixOperatorDecl : public OperatorDecl { SourceLoc InfixLoc, AssociativityLoc, AssociativityValueLoc, PrecedenceLoc, PrecedenceValueLoc; public: InfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, SourceLoc InfixLoc, Identifier Name, SourceLoc NameLoc, SourceLoc LBraceLoc, SourceLoc AssociativityLoc, SourceLoc AssociativityValueLoc, SourceLoc PrecedenceLoc, SourceLoc PrecedenceValueLoc, SourceLoc RBraceLoc, InfixData InfixData) : OperatorDecl(DeclKind::InfixOperator, DC, OperatorLoc, Name, NameLoc, LBraceLoc, RBraceLoc), InfixLoc(InfixLoc), AssociativityLoc(AssociativityLoc), AssociativityValueLoc(AssociativityValueLoc), PrecedenceLoc(PrecedenceLoc), PrecedenceValueLoc(PrecedenceValueLoc) { if (!InfixData.isValid()) { setInvalid(); } else { InfixOperatorDeclBits.Precedence = InfixData.getPrecedence(); InfixOperatorDeclBits.Associativity = static_cast(InfixData.getAssociativity()); } } SourceLoc getInfixLoc() const { return InfixLoc; } SourceLoc getAssociativityLoc() const { return AssociativityLoc; } SourceLoc getAssociativityValueLoc() const { return AssociativityValueLoc; } SourceLoc getPrecedenceLoc() const { return PrecedenceLoc; } SourceLoc getPrecedenceValueLoc() const { return PrecedenceValueLoc; } unsigned getPrecedence() const { return InfixOperatorDeclBits.Precedence; } Associativity getAssociativity() const { return Associativity(InfixOperatorDeclBits.Associativity); } InfixData getInfixData() const { if (isInvalid()) return InfixData(); return InfixData(getPrecedence(), getAssociativity()); } /// True if this decl's attributes conflict with those declared by another /// operator. bool conflictsWith(InfixOperatorDecl *other) { return getInfixData() != other->getInfixData(); } static bool classof(const Decl *D) { return D->getKind() == DeclKind::InfixOperator; } }; /// Declares the behavior of a prefix operator. For example: /// /// \code /// operator prefix /+/ {} /// \endcode class PrefixOperatorDecl : public OperatorDecl { SourceLoc PrefixLoc; public: PrefixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, SourceLoc PrefixLoc, Identifier Name, SourceLoc NameLoc, SourceLoc LBraceLoc, SourceLoc RBraceLoc) : OperatorDecl(DeclKind::PrefixOperator, DC, OperatorLoc, Name, NameLoc, LBraceLoc, RBraceLoc), PrefixLoc(PrefixLoc) {} SourceLoc getPrefixLoc() const { return PrefixLoc; } /// True if this decl's attributes conflict with those declared by another /// PrefixOperatorDecl. bool conflictsWith(PrefixOperatorDecl *other) { return false; } static bool classof(const Decl *D) { return D->getKind() == DeclKind::PrefixOperator; } }; /// Declares the behavior of a postfix operator. For example: /// /// \code /// operator postfix /+/ {} /// \endcode class PostfixOperatorDecl : public OperatorDecl { SourceLoc PostfixLoc; public: PostfixOperatorDecl(DeclContext *DC, SourceLoc OperatorLoc, SourceLoc PostfixLoc, Identifier Name, SourceLoc NameLoc, SourceLoc LBraceLoc, SourceLoc RBraceLoc) : OperatorDecl(DeclKind::PostfixOperator, DC, OperatorLoc, Name, NameLoc, LBraceLoc, RBraceLoc), PostfixLoc(PostfixLoc) {} SourceLoc getPostfixLoc() const { return PostfixLoc; } /// True if this decl's attributes conflict with those declared by another /// PostfixOperatorDecl. bool conflictsWith(PostfixOperatorDecl *other) { return false; } static bool classof(const Decl *D) { return D->getKind() == DeclKind::PostfixOperator; } }; inline void GenericParam::setDeclContext(DeclContext *DC) { TypeParam->setDeclContext(DC); } inline bool ValueDecl::isSettable() const { if (auto vd = dyn_cast(this)) { return vd->isSettable(); } else if (auto sd = dyn_cast(this)) { return sd->isSettable(); } else return false; } inline bool NominalTypeDecl::isStoredProperty(VarDecl *vd) { return !vd->isStatic() && !vd->isComputed(); } inline MutableArrayRef AbstractFunctionDecl::getArgParamBuffer() { switch (getKind()) { case DeclKind::Constructor: return MutableArrayRef(&cast(this)->ArgParams, 1); case DeclKind::Destructor: return {}; case DeclKind::Func: { auto *FD = cast(this); return MutableArrayRef(reinterpret_cast(FD + 1), FD->getNumParamPatternsImpl()); } default: llvm_unreachable("unhandled derived decl kind"); } } inline MutableArrayRef AbstractFunctionDecl::getBodyParamBuffer() { switch (getKind()) { case DeclKind::Constructor: return MutableArrayRef(&cast(this)->BodyParams, 1); case DeclKind::Destructor: return {}; case DeclKind::Func: { auto *FD = cast(this); unsigned NumParamPatterns = FD->getNumParamPatternsImpl(); return MutableArrayRef( reinterpret_cast(FD + 1) + NumParamPatterns, NumParamPatterns); } default: llvm_unreachable("unhandled derived decl kind"); } } } // end namespace swift #endif