//===--- 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/LazyResolver.h" #include "swift/AST/Requirement.h" #include "swift/AST/Substitution.h" #include "swift/AST/Type.h" #include "swift/AST/TypeLoc.h" #include "swift/Basic/Range.h" #include "swift/Basic/SourceLoc.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallPtrSet.h" #include namespace clang { class Decl; class MacroInfo; class SourceLocation; } namespace swift { class ApplyExpr; class ArchetypeBuilder; class ArchetypeType; class ASTContext; class ASTPrinter; class ASTWalker; class DestructorDecl; class DiagnosticEngine; class DynamicSelfType; class Type; class Expr; class LiteralExpr; class FuncDecl; class BraceStmt; class DeclAttributes; class GenericSignature; class GenericTypeParamDecl; class GenericTypeParamType; class Module; class NameAliasType; class EnumElementDecl; class Pattern; struct PrintOptions; class ProtocolDecl; class ProtocolType; struct RawComment; enum class Resilience : unsigned char; class TypeAliasDecl; class Stmt; class SubscriptDecl; class ValueDecl; class VarDecl; /// Represents a clang declaration or a macro. class ClangNode { llvm::PointerUnion Ptr; public: ClangNode() = default; ClangNode(const clang::Decl *D) : Ptr(D) {} ClangNode(clang::MacroInfo *MI) : Ptr(MI) {} bool isNull() const { return Ptr.isNull(); } explicit operator bool() const { return !isNull(); } const clang::Decl *getAsDecl() const { return Ptr.dyn_cast(); } clang::MacroInfo *getAsMacro() const { return Ptr.dyn_cast(); } clang::SourceLocation getLocation() const; }; 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" }; /// Fine-grained declaration kind that provides a description of the /// kind of entity a declaration represents, as it would be used in /// diagnostics. /// /// For example, \c FuncDecl is a single declaration class, but it has /// several descriptive entries depending on whether it is an /// operator, global function, local function, method, (observing) /// accessor, etc. enum class DescriptiveDeclKind : uint8_t { Import, Extension, EnumCase, TopLevelCode, IfConfig, PatternBinding, Var, Let, StaticVar, StaticLet, ClassVar, ClassLet, InfixOperator, PrefixOperator, PostfixOperator, TypeAlias, GenericTypeParam, AssociatedType, Enum, Struct, Class, Protocol, GenericEnum, GenericStruct, GenericClass, Subscript, Constructor, Destructor, LocalFunction, GlobalFunction, OperatorFunction, Method, StaticMethod, ClassMethod, Getter, Setter, WillSet, DidSet, EnumElement, }; /// 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 }; /// Keeps track of whrther a given class inherits initializers from its /// superclass. enum class StoredInheritsSuperclassInits { /// We have not yet checked. Unchecked, /// Superclass initializers are not inherited. NotInherited, /// Complete object initializers in the superclass are inherited. Inherited }; /// Describes which spelling was used in the source for the 'static' or 'class' /// keyword. enum class StaticSpellingKind : uint8_t { None, KeywordStatic, KeywordClass, }; /// Describes if an enum element constructor directly or indirectly references /// its enclosing type. enum class ElementRecursiveness { /// The element does not reference its enclosing type. NotRecursive, /// The element is currently being validated, and may references its enclosing /// type. PotentiallyRecursive, /// The element does not reference its enclosing type. Recursive }; /// Diagnostic printing of \c StaticSpellingKind. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, StaticSpellingKind SSK); /// 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; /// \brief Whether 'static' or 'class' was used. unsigned StaticSpelling : 2; /// \brief Whether this pattern binding appears in a conditional statement. unsigned Conditional : 1; }; enum { NumPatternBindingDeclBits = NumDeclBits + 4 }; 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 IsStatic : 1; /// \brief Whether this is a 'let' property, which can only be initialized /// in its declaration, and never assigned to, making it immutable. unsigned IsLet : 1; /// \brief Whether this is a property used in expressions in the debugger. /// It is up to the debugger to instruct SIL how to access this variable. unsigned IsDebuggerVar : 1; }; enum { NumVarDeclBits = NumValueDeclBits + 3 }; static_assert(NumVarDeclBits <= 32, "fits in an unsigned"); class EnumElementDeclBitfields { friend class EnumElementDecl; unsigned : NumValueDeclBits; /// \brief Whether or not this element directly or indirectly references /// the enum type. unsigned Recursiveness : 2; }; enum { NumEnumElementDeclBits = NumValueDeclBits + 2 }; static_assert(NumEnumElementDeclBits <= 32, "fits in an unsigned"); class AbstractFunctionDeclBitfields { friend class AbstractFunctionDecl; unsigned : NumValueDeclBits; /// \see AbstractFunctionDecl::BodyKind unsigned BodyKind : 3; /// \brief Whether this function was declared with a selector-style /// signature. unsigned HasSelectorStyleSignature : 1; /// Number of curried parameter patterns (tuples). unsigned NumParamPatterns : 7; }; enum { NumAbstractFunctionDeclBits = NumValueDeclBits + 11 }; static_assert(NumAbstractFunctionDeclBits <= 32, "fits in an unsigned"); class FuncDeclBitfields { friend class FuncDecl; unsigned : NumAbstractFunctionDeclBits; /// Whether this function is a 'static' method. unsigned IsStatic : 1; /// \brief Whether 'static' or 'class' was used. unsigned StaticSpelling : 2; /// Whether this function is a 'mutating' method. unsigned Mutating : 1; /// Whether this function has a dynamic Self return type. unsigned HasDynamicSelf : 1; }; enum { NumFuncDeclBits = NumAbstractFunctionDeclBits + 5 }; static_assert(NumFuncDeclBits <= 32, "fits in an unsigned"); class ConstructorDeclBitfields { friend class ConstructorDecl; unsigned : NumAbstractFunctionDeclBits; /// The body initialization kind (+1), or zero if not yet computed. /// /// This value is cached but is not serialized, because it is a property /// of the definition of the constructor that is useful only to semantic /// analysis and SIL generation. unsigned ComputedBodyInitKind : 3; /// Whether this is a complete object initializer. unsigned CompleteObjectInit : 1; /// Whether this initializer is a stub placed into a subclass to /// catch invalid delegations to a subobject initializer not /// overridden by the subclass. A stub will always trap at runtime. /// /// Initializer stubs can be invoked from Objective-C or through /// the Objective-C runtime; there is no way to directly express /// an object construction that will invoke a stub. unsigned HasStubImplementation : 1; }; enum { NumConstructorDeclBits = NumAbstractFunctionDeclBits + 6 }; static_assert(NumConstructorDeclBits <= 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"); class NominalTypeDeclBitFields { friend class NominalTypeDecl; unsigned : NumTypeDeclBits; /// Whether or not the nominal type decl has delayed protocol or member /// declarations. unsigned HasDelayedMembers : 1; }; enum { NumNominalTypeDeclBits = NumTypeDeclBits + 1 }; 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; /// Whether this class requires all of its instance variables to /// have in-class initializers. unsigned RequiresStoredPropertyInits : 1; /// Whether this class inherits its superclass's complete object /// initializers. /// /// This is a value of \c StoredInheritsSuperclassInits. unsigned InheritsSuperclassInits : 2; /// Whether we have already added implicitly-defined initializers /// to this class. unsigned AddedImplicitInitializers : 1; }; enum { NumClassDeclBits = NumNominalTypeDeclBits + 6 }; 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; EnumElementDeclBitfields EnumElementDeclBits; FuncDeclBitfields FuncDeclBits; ConstructorDeclBitfields ConstructorDeclBits; TypeDeclBitfields TypeDeclBits; NominalTypeDeclBitFields NominalTypeDeclBits; 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() const; 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); /// Retrieve the descriptive kind for this declaration. DescriptiveDeclKind getDescriptiveKind() const; /// Produce a name for the given descriptive declaration kind, which /// is suitable for use in diagnostics. static StringRef getDescriptiveKindName(DescriptiveDeclKind 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(); } /// Returns the starting location of the entire declaration. SourceLoc getStartLoc() const { return getSourceRange().Start; } /// Returns the end location of the entire declaration. SourceLoc getEndLoc() const { return getSourceRange().End; } /// Returns the preferred location when referring to declarations /// in diagnostics. SourceLoc getLoc() const; /// Returns the source range of the entire declaration. 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; void print(raw_ostream &OS, const PrintOptions &Opts) const; /// \brief Pretty-print the given declaration. /// /// \param Printer ASTPrinter object. /// /// \param Opts Options to control how pretty-printing is performed. void print(ASTPrinter &Printer, const PrintOptions &Opts) const; /// \brief Determine whether this declaration should be printed when /// encountered in its declaration context's list of members. bool shouldPrintInContext(const PrintOptions &PO) 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; } /// \returns the unparsed comment attached to this declaration. RawComment getRawComment() const; /// \returns the brief comment attached to this declaration. StringRef getBriefComment() const; /// \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() const { if (!DeclBits.FromClang) return ClangNode(); return getClangNodeSlow(); } /// \brief Retrieve the Clang declaration from which this declaration was /// synthesized, if any. const clang::Decl *getClangDecl() const { if (!DeclBits.FromClang) return nullptr; return getClangNodeSlow().getAsDecl(); } /// \brief Retrieve the Clang macro from which this declaration was /// synthesized, if any. clang::MacroInfo *getClangMacro() { if (!DeclBits.FromClang) return nullptr; return getClangNodeSlow().getAsMacro(); } /// \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; } }; template (GenericParamList::*accessor)() const> class NestedGenericParamListIterator; /// 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; /// The builder used to build archetypes for this list. ArchetypeBuilder *Builder; GenericParamList(SourceLoc LAngleLoc, ArrayRef Params, SourceLoc WhereLoc, MutableArrayRef Requirements, SourceLoc RAngleLoc); void getAsGenericSignatureElements(ASTContext &C, llvm::DenseMap &archetypeMap, SmallVectorImpl &genericParams, SmallVectorImpl &requirements) const; // Don't copy. GenericParamList(const GenericParamList &) = delete; GenericParamList &operator=(const GenericParamList &) = delete; 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); /// Create a new generic parameter list with the same parameters and /// requirements as this one, but parented to a different outer parameter /// list. GenericParamList *cloneWithOuterParameters(const ASTContext &Context, GenericParamList *Outer) { auto clone = create(Context, SourceLoc(), getParams(), SourceLoc(), getRequirements(), SourceLoc()); clone->setAllArchetypes(getAllArchetypes()); clone->setOuterParameters(Outer); return clone; } /// Create an empty generic parameter list. static GenericParamList *getEmpty(ASTContext &Context) { // TODO: Could probably unique this in the AST context. return create(Context, SourceLoc(), {}, SourceLoc(), {}, SourceLoc()); } 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(); } /// Get the total number of parameters, including those from parent generic /// parameter lists. unsigned totalSize() const { return NumParams + (OuterParameters ? OuterParameters->totalSize() : 0); } /// \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). /// /// This does not include archetypes from the outer generic parameter list(s). ArrayRef getAllArchetypes() const { return AllArchetypes; } /// \brief Return the number of primary archetypes. unsigned getNumPrimaryArchetypes() const { return size(); } /// \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, getNumPrimaryArchetypes()); } /// \brief Retrieves the list containing only the associated archetypes. ArrayRef getAssociatedArchetypes() const { return getAllArchetypes().slice(getNumPrimaryArchetypes()); } /// \brief Sets all archetypes *without* copying the source array. void setAllArchetypes(ArrayRef AA) { assert(AA.size() >= size() && "allArchetypes is smaller than number of generic params?!"); AllArchetypes = AA; } using NestedArchetypeIterator = NestedGenericParamListIterator; using NestedGenericParamIterator = NestedGenericParamListIterator; /// \brief Retrieves a list containing all archetypes from this generic /// parameter clause and all outer generic parameter clauses in outer-to- /// inner order. Range getAllNestedArchetypes() const; /// \brief Retrieves a list containing all generic parameter records from /// this generic parameter clause and all outer generic parameter clauses in /// outer-to-inner order. Range getNestedGenericParams() const; /// \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; } SourceLoc getLAngleLoc() const { return Brackets.Start; } SourceLoc getRAngleLoc() const { return Brackets.End; } 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; } /// Get the generic parameter list as a GenericSignature in which the generic /// parameters have been canonicalized. /// /// \param archetypeMap This DenseMap is populated with a mapping of /// context primary archetypes to dependent generic /// types. GenericSignature *getAsCanonicalGenericSignature( llvm::DenseMap &archetypeMap, ASTContext &C) const; /// Derive a type substitution map for this generic parameter list from a /// matching substitution vector. TypeSubstitutionMap getSubstitutionMap(ArrayRef Subs) const; /// Derive the all-archetypes list for the given list of generic /// parameters. static ArrayRef deriveAllArchetypes(ArrayRef params, SmallVectorImpl &archetypes); void setBuilder(ArchetypeBuilder *builder) { Builder = builder; } ArchetypeBuilder *getBuilder() const { return Builder; } /// Collect the nested archetypes of an archetype into the given /// collection. /// /// \param known - the set of archetypes already present in `all` /// \param all - the output list of archetypes static void addNestedArchetypes(ArchetypeType *archetype, SmallPtrSetImpl &known, SmallVectorImpl &all); void print(raw_ostream &OS); void dump(); }; /// An iterator template for lazily walking a nested generic parameter list. template (GenericParamList::*accessor)() const> class NestedGenericParamListIterator { SmallVector stack; ArrayRef elements; void refreshElements() { while (elements.empty()) { stack.pop_back(); if (stack.empty()) break; elements = (stack.back()->*accessor)(); } } public: // Create a 'begin' iterator for a generic param list. NestedGenericParamListIterator(const GenericParamList *params) { // Walk up to the outermost list to create a stack of lists to walk. while (params) { stack.push_back(params); params = params->getOuterParameters(); } // If the stack is empty, be like the 'end' iterator. if (stack.empty()) return; elements = (stack.back()->*accessor)(); refreshElements(); } // Create an 'end' iterator. NestedGenericParamListIterator() {} // Iterator dereference. const T &operator*() const { return elements[0]; } const T *operator->() const { return &elements[0]; } // Iterator advancement. NestedGenericParamListIterator &operator++() { elements = elements.slice(1); refreshElements(); return *this; } NestedGenericParamListIterator operator++(int) { auto copy = *this; ++(*this); return copy; } // Ghetto comparison. Only true if end() == end(). bool operator==(const NestedGenericParamListIterator &o) const { return stack.empty() && o.stack.empty(); } bool operator!=(const NestedGenericParamListIterator &o) const { return !stack.empty() || !o.stack.empty(); } // An empty range of nested archetypes. static Range emptyRange() { return {{}, {}}; } }; using NestedArchetypeIterator = GenericParamList::NestedArchetypeIterator; using NestedGenericParamIterator = GenericParamList::NestedGenericParamIterator; inline Range GenericParamList::getAllNestedArchetypes() const { return {NestedArchetypeIterator(this), NestedArchetypeIterator()}; } inline Range GenericParamList::getNestedGenericParams() const { return {NestedGenericParamIterator(this), NestedGenericParamIterator()}; } /// 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); /// Returns the import kind that is most appropriate for \p VD. /// /// Note that this will never return \c Type; an imported typealias will use /// the more specific kind from its underlying type. static ImportKind getBestImportKind(const ValueDecl *VD); /// Returns the most appropriate import kind for the given list of decls. /// /// If the list is non-homogenous, or if there is more than one decl that /// cannot be overloaded, returns Nothing. static Optional findBestImportKind(ArrayRef Decls); 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; LazyLoaderArray 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. LazyLoaderArray 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(bool forceDelayedMembers = true) const { return Protocols; } void setProtocols(ArrayRef protocols) { Protocols = protocols; } GenericParamList *getGenericParams() const; /// \brief Retrieve the set of protocol conformance mappings for this type. /// /// Calculated during type-checking. ArrayRef getConformances() const; void setConformances(ArrayRef c) { Conformances = c; } void setConformanceLoader(LazyMemberLoader *resolver, uint64_t contextData); ArrayRef getMembers(bool forceDelayedMembers = true) const; void setMembers(ArrayRef M, SourceRange B); void setMemberLoader(LazyMemberLoader *resolver, uint64_t contextData); bool hasLazyMembers() const { return Members.isLazy(); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == DeclKind::Extension; } template 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; } }; /// \brief This decl contains a pattern and optional initializer for a set /// of one or more VarDecls declared together. /// /// For example, in /// \code /// var (a, b) = foo() /// \endcode /// 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/class' 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, StaticSpellingKind StaticSpelling, SourceLoc VarLoc, Pattern *Pat, Expr *E, bool isConditional, DeclContext *Parent) : Decl(DeclKind::PatternBinding, Parent), StaticLoc(StaticLoc), VarLoc(VarLoc), Pat(Pat), InitAndChecked(E, false) { PatternBindingDeclBits.IsStatic = StaticLoc.isValid(); PatternBindingDeclBits.StaticSpelling = static_cast(StaticSpelling); PatternBindingDeclBits.Conditional = isConditional; } 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); } /// Does this binding declare something that requires storage? bool hasStorage() const; /// Does this binding appear in an 'if' or 'while' condition? bool isConditional() const { return PatternBindingDeclBits.Conditional; } bool isStatic() const { return PatternBindingDeclBits.IsStatic; } void setStatic(bool s) { PatternBindingDeclBits.IsStatic = s; } SourceLoc getStaticLoc() const { return StaticLoc; } /// \returns the way 'static'/'class' was spelled in the source. StaticSpellingKind getStaticSpelling() const { return static_cast( PatternBindingDeclBits.StaticSpelling); } /// \returns the way 'static'/'class' should be spelled for this declaration. StaticSpellingKind getCorrectStaticSpelling() const; 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 a SourceFile. The primary reason for building these is to give /// top-level statements a DeclContext which is distinct from the file 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; }; /// IfConfigDecl - This class represents the declaration-side representation of /// #if/#else/#endif blocks. Active and inactive block members are stored /// separately, with the intention being that active members will be handed /// back to the enclosing declaration. class IfConfigDecl : public Decl { ArrayRef ThenMembers; ArrayRef ElseMembers; bool IfBlockIsActive; SourceLoc IfLoc; SourceLoc ElseLoc; SourceLoc EndLoc; Expr *Cond; public: IfConfigDecl(DeclContext *Parent, bool IfBlockIsActive, SourceLoc ifLoc, SourceLoc elseLoc, SourceLoc endLoc, Expr *cond, ArrayRef ThenMembers, ArrayRef ElseMembers): Decl(DeclKind::IfConfig, Parent), ThenMembers(ThenMembers), ElseMembers(ElseMembers), IfBlockIsActive(IfBlockIsActive), IfLoc(ifLoc), ElseLoc(elseLoc), EndLoc(endLoc), Cond(cond) {} ArrayRef getThenMembers() const { return ThenMembers; } ArrayRef getElseMembers() const { return ElseMembers; } ArrayRef getActiveMembers() const { return IfBlockIsActive ? ThenMembers : ElseMembers; } ArrayRef getInactiveMembers() const { return !IfBlockIsActive ? ThenMembers : ElseMembers; } Expr *getCond() { return Cond; } bool isIfBlockActive() const { return IfBlockIsActive; } bool hasElse() const { return ElseLoc.isValid(); } SourceLoc getIfLoc() const { return IfLoc; } SourceLoc getElseLoc() const { return ElseLoc; } SourceLoc getEndLoc() const { return EndLoc; } SourceLoc getLoc() const { return getIfLoc(); } SourceRange getSourceRange() const; SourceRange getInactiveSourceRange() const { if (isIfBlockActive()) { if (hasElse()) return SourceRange(ElseLoc, EndLoc); else return SourceRange(); } return SourceRange(IfLoc, ElseLoc.isValid() ? ElseLoc : EndLoc); } static bool classof(const Decl *D) { return D->getKind() == DeclKind::IfConfig; } }; /// ValueDecl - All named decls that are values in the language. These can /// have a type, etc. class ValueDecl : public Decl { DeclName Name; SourceLoc NameLoc; Type Ty; protected: ValueDecl(DeclKind K, DeclContext *DC, DeclName 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; bool hasName() const { return bool(Name); } /// TODO: Rename to getSimpleName? Identifier getName() const { return Name.getBaseName(); } bool isOperator() const { return Name.isOperator(); } /// TODO: Rename to getName? DeclName getFullName() const { return Name; } 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(); /// Get the innermost declaration context that can provide generic /// parameters used within this declaration. const DeclContext *getPotentialGenericDeclContext() const { return const_cast(this)->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; bool hasInterfaceType() const { return !!InterfaceTy; } /// Set the interface type for the given value. void setInterfaceType(Type type); /// 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(DeclContext *UseDC) 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 context discriminator for this local value, which /// is the index of this declaration in the sequence of /// discriminated declarations with the same name in the current /// context. Only local functions and variables with getters and /// setters have discriminators. unsigned getLocalDiscriminator() const; void setLocalDiscriminator(unsigned index); /// Retrieve the declaration that this declaration overrides, if any. ValueDecl *getOverriddenDecl() const; /// Returns true if the decl requires Objective-C interop. /// /// This can be true even if there is no 'objc' attribute on the declaration. /// In that case it was inferred by the type checker. bool isObjC() const { return AttrsAndIsObjC.getInt(); } void setIsObjC(bool value) { AttrsAndIsObjC.setInt(value); } /// Is this declaration marked with the @final attribute? bool isFinal() const { return getAttrs().hasAttribute(); } /// 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(); /// Return true if a DeclRefExpr or MemberRefExpr use of this value is /// "direct" when being used in the specified context. bool isUseFromContextDirect(const DeclContext *DC) const; /// 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; 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; } /// \brief The set of protocols to which this type conforms. ArrayRef Protocols; 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(bool forceDelayedMembers = true) const { return Protocols; } void setProtocols(ArrayRef protocols) { assert((!TypeDeclBits.ProtocolsSet || protocols.empty()) && "protocols already set"); TypeDeclBits.ProtocolsSet = true; Protocols = protocols; } bool isProtocolsValid() const { return TypeDeclBits.ProtocolsSet; } 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); 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; /// The default definition. TypeLoc DefaultDefinition; LazyMemberLoader *Resolver = nullptr; uint64_t ResolverContextData; public: AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc, Identifier name, SourceLoc nameLoc, TypeLoc defaultDefinition); AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc, Identifier name, SourceLoc nameLoc, LazyMemberLoader *definitionResolver, uint64_t resolverData); /// Get the protocol in which this associated type is declared. ProtocolDecl *getProtocol() const { return cast(getDeclContext()); } /// Retrieve the default definition type. Type getDefaultDefinitionType() const { return getDefaultDefinitionLoc().getType(); } TypeLoc &getDefaultDefinitionLoc(); const TypeLoc &getDefaultDefinitionLoc() const { return const_cast(this)->getDefaultDefinitionLoc(); } 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); } using difference_type = ptrdiff_t; using value_type = FilterDeclType *; using pointer = FilterDeclType * const *; using reference = FilterDeclType * const &; using iterator_category = std::forward_iterator_tag; }; 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(); } }; /// Iterator that walks the generic parameter types declared in a generic /// signature and their dependent members. class GenericSignatureWitnessIterator { ArrayRef p; public: GenericSignatureWitnessIterator() = default; GenericSignatureWitnessIterator(ArrayRef p) : p(p) { assert(p.empty() || p.front().getKind() == RequirementKind::WitnessMarker); } GenericSignatureWitnessIterator &operator++() { do { p = p.slice(1); } while (!p.empty() && p.front().getKind() != RequirementKind::WitnessMarker); return *this; } GenericSignatureWitnessIterator operator++(int) { auto copy = *this; ++(*this); return copy; } Type operator*() const { assert(p.front().getKind() == RequirementKind::WitnessMarker); return p.front().getFirstType(); } Type operator->() const { assert(p.front().getKind() == RequirementKind::WitnessMarker); return p.front().getFirstType(); } bool operator==(const GenericSignatureWitnessIterator &o) { return p.data() == o.p.data() && p.size() == o.p.size(); } bool operator!=(const GenericSignatureWitnessIterator &o) { return p.data() != o.p.data() || p.size() != o.p.size(); } static GenericSignatureWitnessIterator emptyRange() { return GenericSignatureWitnessIterator(); } // Allow the witness iterator to be used with a ranged for. GenericSignatureWitnessIterator begin() const { return *this; } GenericSignatureWitnessIterator end() const { return GenericSignatureWitnessIterator({p.end(), p.end()}); } }; class GenericSignature; /// Describes the generic signature of a particular declaration, including /// both the generic type parameters and the requirements placed on those /// generic parameters. class GenericSignature : public llvm::FoldingSetNode { 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); llvm::PointerUnion CanonicalSignatureOrASTContext; static ASTContext &getASTContext(ArrayRef params, ArrayRef requirements); public: /// Create a new generic signature with the given type parameters and /// requirements. static GenericSignature *get(ArrayRef params, ArrayRef requirements); /// Create a new generic signature with the given type parameters and /// requirements, first canonicalizing the types. static CanGenericSignature getCanonical(ArrayRef params, ArrayRef requirements); /// 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; } /// Build a substitution map from a vector of Substitutions that correspond to /// the generic parameters in this generic signature. The order of primary /// archetypes in the substitution vector must match the order of generic /// parameters in getGenericParams(). TypeSubstitutionMap getSubstitutionMap(ArrayRef args) const; /// Return a range that iterates through first all of the generic parameters /// of the signature, followed by all of their recursive member types exposed /// through protocol requirements. /// /// The member types are presented in the /// same order as GenericParamList::getAllArchetypes would present for an /// equivalent GenericParamList. GenericSignatureWitnessIterator getAllDependentTypes() const { return GenericSignatureWitnessIterator(getRequirements()); } bool isCanonical() const { return CanonicalSignatureOrASTContext.is(); } ASTContext &getASTContext() const; CanGenericSignature getCanonicalSignature(); /// Uniquing for the ASTContext. void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getGenericParams(), getRequirements()); } static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef genericParams, ArrayRef requirements); void print(raw_ostream &OS) const; void dump() const; }; inline CanGenericSignature::CanGenericSignature(GenericSignature *Signature) : Signature(Signature) { assert(!Signature || Signature->isCanonical()); } inline ArrayRef> CanGenericSignature::getGenericParams() const{ ArrayRef params = Signature->getGenericParams(); auto base = reinterpret_cast*>( params.data()); return {base, params.size()}; } /// Kinds of optional types. enum OptionalTypeKind : unsigned { /// The type is not an optional type. OTK_None, /// The type is Optional. OTK_Optional, /// The type is UncheckedOptional. OTK_UncheckedOptional }; enum { NumOptionalTypeKinds = 2 }; /// An implicitly created member decl, used when importing a Clang enum type. /// These are not added to their enclosing type unless forced. typedef std::function DelayedDecl; /// An implicitly created protocol decl, used when importing a Clang enum type. /// These are not added to their enclosing type unless forced. typedef std::function DelayedProtocolDecl; /// NominalTypeDecl - a declaration of a nominal type, like a struct. This /// decl is always a DeclContext. class NominalTypeDecl : public TypeDecl, public DeclContext { SourceRange Braces; LazyLoaderArray Members; /// \brief The sets of implicit members and protocols added to imported enum /// types. These members and protocols are added to the NominalDecl only if /// the nominal type is directly or indirectly referenced. ArrayRef DelayedMembers; ArrayRef DelayedProtocols; GenericParamList *GenericParams; /// Global declarations that were synthesized on this type's behalf, such as /// default operator definitions derived for protocol conformances. ArrayRef DerivedGlobalDecls; /// \brief The set of protocol conformance mappings. The element order /// corresponds to the order of Protocols returned by getProtocols(). // FIXME: We don't really need this correspondence any more. LazyLoaderArray Conformances; /// \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(nullptr), DeclaredTy(nullptr) { setGenericParams(GenericParams); NominalTypeDeclBits.HasDelayedMembers = false; } friend class ProtocolType; public: using TypeDecl::getASTContext; ArrayRef getMembers(bool forceDelayedMembers = true) const; SourceRange getBraces() const { return Braces; } void setMembers(ArrayRef M, SourceRange B); void setMemberLoader(LazyMemberLoader *resolver, uint64_t contextData); bool hasLazyMembers() const { return Members.isLazy(); } /// \brief Returns true if this this decl contains delayed value or protocol /// declarations. bool hasDelayedMembers() const { return NominalTypeDeclBits.HasDelayedMembers; } /// \brief Mark this declaration as having delayed members or not. void setHasDelayedMembers(bool hasDelayedMembers = true) { NominalTypeDeclBits.HasDelayedMembers = hasDelayedMembers; } 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); /// Set the generic signature of this type. void setGenericSignature(GenericSignature *sig); /// 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(); } /// Retrieve the generic signature. GenericSignature *getGenericSignature() const { return GenericSig; } /// 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() const; /// 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(DeclName name); /// Collect the set of protocols to which this type should implicitly /// conform, such as AnyObject (for classes). void getImplicitProtocols(SmallVectorImpl &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; void setConformances(ArrayRef c) { Conformances = c; } void setConformanceLoader(LazyMemberLoader *resolver, uint64_t contextData); using TypeDecl::getDeclaredInterfaceType; /// classifyAsOptionalType - Decide whether this declaration is one /// of the library-intrinsic Optional or UncheckedOptional types. OptionalTypeKind classifyAsOptionalType() const; private: /// Predicate used to filter StoredPropertyRange. static bool isStoredProperty(VarDecl *vd); // at end of file /// Force delayed implicit protocol declarations to be added to the type /// declaration. void forceDelayedProtocolDecls(); /// Force delayed implicit member declarations to be added to the type /// declaration. void forceDelayedMemberDecls(); 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()); } ArrayRef getDerivedGlobalDecls() const { return DerivedGlobalDecls; } void setDerivedGlobalDecls(MutableArrayRef decls) { DerivedGlobalDecls = decls; } bool hasDelayedMemberDecls() { return DelayedMembers.size() != 0; } void setDelayedMemberDecls(ArrayRef delayedMembers) { DelayedMembers = delayedMembers; setHasDelayedMembers(); } bool hasDelayedProtocolDecls() { return DelayedProtocols.size() != 0; } void setDelayedProtocolDecls(ArrayRef delayedProtocols) { DelayedProtocols = delayedProtocols; setHasDelayedMembers(); } /// Force delayed implicit member and protocol declarations to be added to the /// type declaration. void forceDelayed() { forceDelayedProtocolDecls(); forceDelayedMemberDecls(); } /// Override of getProtocols that forces any delayed protocol members to be /// resolved before returning the protocol array. ArrayRef getProtocols(bool forceDelayedMembers = true) const; // 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; } /// True if the enum is a "simple" enum, and none of its cases have associated /// payloads. bool isSimpleEnum() const; }; /// 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); } //// Whether this class requires all of its stored properties to //// have initializers in the class definition. bool requiresStoredPropertyInits() const { return ClassDeclBits.RequiresStoredPropertyInits; } /// Set whether this class requires all of its stored properties to /// have initializers in the class definition. void setRequiresStoredPropertyInits(bool requiresInits) { ClassDeclBits.RequiresStoredPropertyInits = requiresInits; } /// Retrieve the destructor for this class. DestructorDecl *getDestructor(); /// Determine whether this class inherits the complete object initializers /// from its superclass. /// /// \param resolver Used to resolve the signatures of initializers, which is /// required for name lookup. bool inheritsSuperclassInitializers(LazyResolver *resolver); /// Determine whether we have already attempted to add any /// implicitly-defined initializers to this class. bool addedImplicitInitializers() const { return ClassDeclBits.AddedImplicitInitializers; } /// Note that we have attempted void setAddedImplicitInitializers() { ClassDeclBits.AddedImplicitInitializers = true; } /// Retrieve the name to use for this class when interoperating with /// the Objective-C runtime. StringRef getObjCRuntimeName(llvm::SmallVectorImpl &buffer); // 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); } /// Retrieve the name to use for this protocol when interoperating /// with the Objective-C runtime. StringRef getObjCRuntimeName(llvm::SmallVectorImpl &buffer); // 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)); } }; /// AbstractStorageDecl - This is the common superclass for VarDecl and /// SubscriptDecl, representing potentially settable memory locations. class AbstractStorageDecl : public ValueDecl { public: enum StorageKindTy { /// There are bits stored in memory for this object, and they are accessed /// directly. Stored, /// This is a stored property with trivial accessors which simply get and /// set the underlying storage. This is not valid for a SubscriptDecl, /// since they never have storage. /// /// These accessors are used for several different purposes: /// 1) In an @objc variable, these accessors are dynamically dispatched /// to and may be overridden. /// 2) When a stored property satisfies a protocol requirement, these /// accessors end up as entries in the witness table. /// 3) Perhaps someday these will be used by accesses outside of this /// resilience domain, when the owning type is resilient. /// StoredWithTrivialAccessors, /// There is no memory associated with this decl anywhere. It is accessed /// by calling a getter and setter. If the setter is absent, then the value /// is only loadable, but not storable. Computed, /// This property has storage, a didSet specifier, a willSet specifier, or /// both. Sema synthesizes a getter and setter that use these. Observing }; private: llvm::PointerIntPair OverriddenDecl; struct GetSetRecord { SourceRange Braces; FuncDecl *Get = nullptr; // User-defined getter FuncDecl *Set = nullptr; // User-defined setter }; struct ObservingRecord : GetSetRecord { FuncDecl *WillSet = nullptr; // willSet(value): FuncDecl *DidSet = nullptr; // didSet: }; GetSetRecord *GetSetInfo = nullptr; ObservingRecord &getDidSetInfo() const { assert(getStorageKind() == Observing); return *static_cast(GetSetInfo); } void setStorageKind(StorageKindTy K) { OverriddenDecl.setInt(K); } protected: AbstractStorageDecl(DeclKind Kind, DeclContext *DC, Identifier Name, SourceLoc NameLoc) : ValueDecl(Kind, DC, Name, NameLoc) { OverriddenDecl.setInt(Stored); } public: /// \brief Determine whether this variable is computed, which means it /// has no storage but does have a user-defined getter or setter. /// StorageKindTy getStorageKind() const { return OverriddenDecl.getInt(); } /// \brief Return true if this is a VarDecl that has storage associated with /// it. bool hasStorage() const { switch (getStorageKind()) { case Stored: case StoredWithTrivialAccessors: return true; case Observing: // Observing properties and stored properties with synthesized accessors // have storage, unless they're @override'ing a value in a base class. return getOverriddenDecl() == nullptr; case Computed: return false; } } bool hasAccessorFunctions() const { switch (getStorageKind()) { case Computed: case StoredWithTrivialAccessors: case Observing: return true; case Stored: return false; } } /// Determine whether this property is overridable. bool isOverridable() const { switch (getStorageKind()) { case Computed: case Observing: return true; case Stored: case StoredWithTrivialAccessors: return false; } } /// \brief Turn this into a computed variable, providing a getter and setter. void makeComputed(SourceLoc LBraceLoc, FuncDecl *Get, FuncDecl *Set, SourceLoc RBraceLoc); /// \brief Turn this into a StoredWithTrivialAccessors var, specifying the /// accessors (getter and setter) that go with it. void makeStoredWithTrivialAccessors(FuncDecl *Get, FuncDecl *Set); /// \brief Turn this into a Observing var, providing the didSet/willSet /// specifiers. void makeObserving(SourceLoc LBraceLoc, FuncDecl *WillSet, FuncDecl *DidSet, SourceLoc RBraceLoc); /// \brief Specify the synthesized get/set functions for a Observing var. /// This is used by Sema. void setObservingAccessors(FuncDecl *Get, FuncDecl *Set); SourceRange getBracesRange() const { assert(GetSetInfo && "Not computed!"); return GetSetInfo->Braces; } /// \brief Retrieve the getter used to access the value of this variable. FuncDecl *getGetter() const { return GetSetInfo ? GetSetInfo->Get : nullptr; } /// \brief Retrieve the setter used to mutate the value of this variable. FuncDecl *getSetter() const { return GetSetInfo ? GetSetInfo->Set : nullptr; } /// \brief Return the funcdecl for the willSet specifier if it exists, this is /// only valid on a VarDecl with Observing storage. FuncDecl *getWillSetFunc() const { return getDidSetInfo().WillSet; } /// \brief Return the funcdecl for the didSet specifier if it exists, this is /// only valid on a VarDecl with Observing storage. FuncDecl *getDidSetFunc() const { return getDidSetInfo().DidSet; } /// Return true if this storage needs to be accessed with getters and /// setters for Objective-C. bool usesObjCGetterAndSetter() const; /// Given that this is an Objective-C property or subscript 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 or subscript declaration, /// produce its setter selector in the given buffer (as UTF-8). StringRef getObjCSetterSelector(SmallVectorImpl &buffer) const; AbstractStorageDecl *getOverriddenDecl() const { return OverriddenDecl.getPointer(); } void setOverriddenDecl(AbstractStorageDecl *over) { OverriddenDecl.setPointer(over); } /// Returns the location of 'override' keyword, if any. SourceLoc getOverrideLoc() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= DeclKind::First_AbstractStorageDecl && D->getKind() <= DeclKind::Last_AbstractStorageDecl; } }; /// VarDecl - 'var' and 'let' declarations. class VarDecl : public AbstractStorageDecl { PatternBindingDecl *ParentPattern = nullptr; public: VarDecl(bool IsStatic, bool IsLet, SourceLoc NameLoc, Identifier Name, Type Ty, DeclContext *DC) : AbstractStorageDecl(DeclKind::Var, DC, Name, NameLoc) { VarDeclBits.IsStatic = IsStatic; VarDeclBits.IsLet = IsLet; VarDeclBits.IsDebuggerVar = false; 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 Returns whether the var is settable in the specified context: this /// is either because it is a stored var, because it has a custom setter, or /// is a let member in an initializer. /// /// Pass a null context to check if it's always settable. bool isSettable(DeclContext *UseDC) const; PatternBindingDecl *getParentPattern() const { return ParentPattern; } void setParentPattern(PatternBindingDecl *PBD) { ParentPattern = PBD; } VarDecl *getOverriddenDecl() const { return cast_or_null(AbstractStorageDecl::getOverriddenDecl()); } /// Determine whether this declaration is an anonymous closure parameter. bool isAnonClosureParam() const; /// Is this a type ('static') variable? bool isStatic() const { return VarDeclBits.IsStatic; } void setStatic(bool IsStatic) { VarDeclBits.IsStatic = IsStatic; } /// \returns the way 'static'/'class' should be spelled for this declaration. StaticSpellingKind getCorrectStaticSpelling() const; /// Is this an immutable 'let' property? bool isLet() const { return VarDeclBits.IsLet; } void setLet(bool IsLet) { VarDeclBits.IsLet = IsLet; } /// Is this a special debugger variable? bool isDebuggerVar() const { return VarDeclBits.IsDebuggerVar; } void setDebuggerVar(bool IsDebuggerVar) { VarDeclBits.IsDebuggerVar = IsDebuggerVar; } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == DeclKind::Var; } }; /// 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. /// class SubscriptDecl : public AbstractStorageDecl { SourceLoc ArrowLoc; Pattern *Indices; TypeLoc ElementTy; public: SubscriptDecl(Identifier NameHack, SourceLoc SubscriptLoc, Pattern *Indices, SourceLoc ArrowLoc, TypeLoc ElementTy, DeclContext *Parent) : AbstractStorageDecl(DeclKind::Subscript, Parent, NameHack, SubscriptLoc), ArrowLoc(ArrowLoc), Indices(nullptr), ElementTy(ElementTy) { setIndices(Indices); } void setAccessors(SourceRange Braces, FuncDecl *Get, FuncDecl *Set) { assert(Get && "subscripts should always have at least a getter"); makeComputed(Braces.Start, Get, Set, Braces.End); } 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); /// \brief Retrieve the type of the element referenced by a subscript /// operation. Type getElementType() const { return ElementTy.getType(); } TypeLoc &getElementTypeLoc() { return ElementTy; } const TypeLoc &getElementTypeLoc() const { return ElementTy; } /// \brief Returns whether the subscript operation has a setter. bool isSettable() const { return getSetter() != nullptr; } /// Determine the kind of Objective-C subscripting this declaration /// implies. ObjCSubscriptKind getObjCSubscriptKind() const; SubscriptDecl *getOverriddenDecl() const { return cast_or_null( AbstractStorageDecl::getOverriddenDecl()); } static bool classof(const Decl *D) { return D->getKind() == DeclKind::Subscript; } }; /// \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, /// Function body will be synthesized on demand. Synthesize }; BodyKind getBodyKind() const { return BodyKind(AbstractFunctionDeclBits.BodyKind); } using BodySynthesizer = void (*)(AbstractFunctionDecl *); 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; /// This enum member is active if getBodyKind() == BodyKind::Synthesize. BodySynthesizer Synthesizer; /// The 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. SourceRange BodyRange; }; GenericParamList *GenericParams; CaptureInfo Captures; AbstractFunctionDecl(DeclKind Kind, DeclContext *Parent, DeclName Name, SourceLoc NameLoc, unsigned NumParamPatterns, GenericParamList *GenericParams) : ValueDecl(Kind, Parent, Name, NameLoc), DeclContext(DeclContextKind::AbstractFunctionDecl, Parent), Body(nullptr), GenericParams(nullptr) { setBodyKind(BodyKind::None); setGenericParams(GenericParams); AbstractFunctionDeclBits.HasSelectorStyleSignature = false; AbstractFunctionDeclBits.NumParamPatterns = NumParamPatterns; // Verify no bitfield truncation. assert(AbstractFunctionDeclBits.NumParamPatterns == NumParamPatterns); } MutableArrayRef getArgParamBuffer(); MutableArrayRef getBodyParamBuffer(); void setBodyKind(BodyKind K) { AbstractFunctionDeclBits.BodyKind = unsigned(K); } void setGenericParams(GenericParamList *GenericParams); 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(bool canSynthesize = true) const { if (canSynthesize && getBodyKind() == BodyKind::Synthesize) { const_cast(this)->setBodyKind(BodyKind::None); (*Synthesizer)(const_cast(this)); } 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(SourceRange bodyRange) { assert(getBodyKind() == BodyKind::None); BodyRange = bodyRange; setBodyKind(BodyKind::Skipped); } /// \brief Note that parsing for the body was delayed. void setBodyDelayed(SourceRange bodyRange) { assert(getBodyKind() == BodyKind::None); BodyRange = bodyRange; setBodyKind(BodyKind::Unparsed); } /// Note that parsing for the body was delayed. void setBodySynthesizer(BodySynthesizer synthesizer) { assert(getBodyKind() == BodyKind::None); Synthesizer = synthesizer; setBodyKind(BodyKind::Synthesize); } /// Retrieve the source range of the function body. SourceRange getBodySourceRange() const; CaptureInfo &getCaptureInfo() { return Captures; } const CaptureInfo &getCaptureInfo() const { return Captures; } bool hasSelectorStyleSignature() const { return AbstractFunctionDeclBits.HasSelectorStyleSignature; } void setHasSelectorStyleSignature() { AbstractFunctionDeclBits.HasSelectorStyleSignature = true; } /// Retrieve the Objective-C selector that names this method. StringRef getObjCSelector(SmallVectorImpl &buffer) const; /// 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; unsigned getNumParamPatterns() const { return AbstractFunctionDeclBits.NumParamPatterns; } /// \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 getNumParamPatterns(); } /// \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 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 interface /// type, or an empty Type() if no 'self' argument should exist. This can /// only be used after name binding has resolved types. /// /// \param isInitializingCtor Specifies whether we're computing the 'self' /// type of an initializing constructor, which accepts an instance 'self' /// rather than a metatype 'self'. Type computeInterfaceSelfType(bool isInitializingCtor); /// \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; /// \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; } /// Retrieve the declaration that this method overrides, if any. AbstractFunctionDecl *getOverriddenDecl() const; 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; // Note that the values of these enums line up with %select values in // diagnostics. enum class AccessorKind { /// \brief This is not a property accessor. NotAccessor = -1, /// \brief This is a getter for a property or subscript. IsGetter = 0, /// \brief This is a setter for a property or subscript. IsSetter = 1, /// \brief This is a willSet specifier for a property. IsWillSet = 2, /// \brief This is a didSet specifier for a property. IsDidSet = 3 }; /// 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; /// \brief If this FuncDecl is an accessor for a property, this indicates /// which property and what kind of accessor. llvm::PointerIntPair AccessorDecl; llvm::PointerUnion OverriddenOrDerivedForDecl; OperatorDecl *Operator; FuncDecl(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, SourceLoc FuncLoc, DeclName Name, SourceLoc NameLoc, unsigned NumParamPatterns, GenericParamList *GenericParams, Type Ty, DeclContext *Parent) : AbstractFunctionDecl(DeclKind::Func, Parent, Name, NameLoc, NumParamPatterns, GenericParams), StaticLoc(StaticLoc), FuncLoc(FuncLoc), OverriddenOrDerivedForDecl(), Operator(nullptr) { FuncDeclBits.IsStatic = StaticLoc.isValid() || getName().isOperator(); FuncDeclBits.StaticSpelling = static_cast(StaticSpelling); assert(NumParamPatterns > 0 && "Must have at least an empty tuple arg"); setType(Ty); FuncDeclBits.Mutating = false; FuncDeclBits.HasDynamicSelf = false; } public: /// Factory function only for use by deserialization. static FuncDecl *createDeserialized(ASTContext &Context, SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, SourceLoc FuncLoc, DeclName Name, SourceLoc NameLoc, GenericParamList *GenericParams, Type Ty, unsigned NumParamPatterns, DeclContext *Parent); static FuncDecl *create(ASTContext &Context, SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, SourceLoc FuncLoc, DeclName Name, SourceLoc NameLoc, GenericParamList *GenericParams, Type Ty, ArrayRef ArgParams, ArrayRef BodyParams, TypeLoc FnRetType, DeclContext *Parent); bool isStatic() const { return FuncDeclBits.IsStatic; } /// \returns the way 'static'/'class' was spelled in the source. StaticSpellingKind getStaticSpelling() const { return static_cast(FuncDeclBits.StaticSpelling); } /// \returns the way 'static'/'class' should be spelled for this declaration. StaticSpellingKind getCorrectStaticSpelling() const; bool isMutating() const { return FuncDeclBits.Mutating; } void setStatic(bool IsStatic = true) { FuncDeclBits.IsStatic = IsStatic; } void setMutating(bool Mutating = true) { FuncDeclBits.Mutating = Mutating; } void setDeserializedSignature(ArrayRef ArgParams, ArrayRef BodyParams, TypeLoc FnRetType); 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; /// makeAccessor - Note that this function is an accessor for the given /// VarDecl or SubscriptDecl. void makeAccessor(AbstractStorageDecl *D, AccessorKind Kind) { assert(Kind != AccessorKind::NotAccessor && "Must specify an accessor kind"); AccessorDecl.setPointerAndInt(D, Kind); } AbstractStorageDecl *getAccessorStorageDecl() const { return AccessorDecl.getPointer(); } AccessorKind getAccessorKind() const { if (AccessorDecl.getPointer() == nullptr) return AccessorKind::NotAccessor; return AccessorDecl.getInt(); } bool isGetter() const { return getAccessorKind() == AccessorKind::IsGetter; } bool isSetter() const { return getAccessorKind() == AccessorKind::IsSetter; } /// isGetterOrSetter - Determine whether this is a getter or a setter vs. /// a normal function. bool isGetterOrSetter() const { return isGetter() || isSetter(); } bool isObservingAccessor() const { return getAccessorKind() == AccessorKind::IsDidSet || getAccessorKind() == AccessorKind::IsWillSet; } bool isAccessor() const { return getAccessorKind() != AccessorKind::NotAccessor; } /// Determine whether this function has a dynamic \c Self return /// type. bool hasDynamicSelf() const { return FuncDeclBits.HasDynamicSelf; } /// Set whether this function has a dynamic \c Self return or not. void setDynamicSelf(bool hasDynamicSelf) { FuncDeclBits.HasDynamicSelf = hasDynamicSelf; } /// Retrieve the dynamic \c Self type for this method, or a null type if /// this method does not have a dynamic \c Self return type. DynamicSelfType *getDynamicSelf() const; /// Retrieve the dynamic \c Self interface type for this method, or /// a null type if this method does not have a dynamic \c Self /// return type. DynamicSelfType *getDynamicSelfInterface() 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; void getLocalCaptures(SmallVectorImpl &Result) const { return getCaptureInfo().getLocalCaptures(this, Result); } /// Get the supertype method this method overrides, if any. FuncDecl *getOverriddenDecl() const { return OverriddenOrDerivedForDecl.dyn_cast(); } void setOverriddenDecl(FuncDecl *over) { // A function cannot be an override if it is also a derived global decl // (since derived decls are at global scope). assert((!OverriddenOrDerivedForDecl || !OverriddenOrDerivedForDecl.is()) && "function cannot be both override and derived global"); OverriddenOrDerivedForDecl = over; } /// Get the type this function was implicitly generated on the behalf of for /// a derived protocol conformance, if any. NominalTypeDecl *getDerivedForTypeDecl() const { return OverriddenOrDerivedForDecl.dyn_cast(); } void setDerivedForTypeDecl(NominalTypeDecl *ntd) { // A function cannot be an override if it is also a derived global decl // (since derived decls are at global scope). assert((!OverriddenOrDerivedForDecl || !OverriddenOrDerivedForDecl.is()) && "function cannot be both override and derived global"); OverriddenOrDerivedForDecl = ntd; } 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; } static bool classof(const AbstractFunctionDecl *D) { return classof(static_cast(D)); } static bool classof(const DeclContext *DC) { if (auto fn = dyn_cast(DC)) return classof(fn); return false; } }; /// \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) { EnumElementDeclBits.Recursiveness = static_cast(ElementRecursiveness::NotRecursive); } 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; ElementRecursiveness getRecursiveness() const { return static_cast(EnumElementDeclBits.Recursiveness); } void setRecursiveness(ElementRecursiveness recursiveness) { EnumElementDeclBits.Recursiveness = static_cast(recursiveness); } 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 {}; } /// ConstructorDecl - Declares a constructor for a type. For example: /// /// \code /// struct X { /// var x : Int /// init(i : Int) { /// x = i /// } /// } /// \endcode class ConstructorDecl : public AbstractFunctionDecl { friend class AbstractFunctionDecl; Pattern *ArgParams[2], *BodyParams[2]; /// The type of the initializing constructor. Type InitializerType; /// The interface type of the initializing constructor. Type InitializerInterfaceType; /// The typechecked call to super.init expression, which needs to be /// inserted at the end of the initializer by SILGen. Expr *CallToSuperInit = nullptr; /// The constructor this overrides, which only makes sense when /// both the overriding and the overridden constructors are abstract. ConstructorDecl *OverriddenDecl = nullptr; public: ConstructorDecl(Identifier NameHack, SourceLoc ConstructorLoc, Pattern *SelfArgParam, Pattern *ArgParams, Pattern *SelfBodyParam, Pattern *BodyParams, GenericParamList *GenericParams, DeclContext *Parent); void setArgParams(Pattern *selfPattern, Pattern *argParams); void setBodyParams(Pattern *selfPattern, Pattern *bodyParams); SourceLoc getConstructorLoc() const { return getNameLoc(); } SourceLoc getStartLoc() const { return getConstructorLoc(); } SourceRange getSourceRange() const; /// 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(); void setInitializerInterfaceType(Type t); /// Get the typechecked call to super.init expression, which needs to be /// inserted at the end of the initializer by SILGen. Expr *getSuperInitCall() { return CallToSuperInit; } void setSuperInitCall(Expr *CallExpr) { CallToSuperInit = CallExpr; } /// Specifies the kind of initialization call performed within the body /// of the constructor, e.g., self.init or super.init. enum class BodyInitKind { /// There are no calls to self.init or super.init. None, /// There is a call to self.init, which delegates to another (peer) /// initializer. Delegating, /// There is a call to super.init, which chains to a superclass initializer. Chained, /// There are no calls to self.init or super.init explicitly in the body of /// the constructor, but a 'super.init' call will be implicitly added /// by semantic analysis. ImplicitChained }; /// Determine whether the body of this constructor contains any delegating /// or superclass initializations (\c self.init or \c super.init, /// respectively) within its body. /// /// \param diags If non-null, this check will ensure that the constructor /// body is consistent in its use of delegation vs. chaining and emit any /// diagnostics through the given diagnostic engine. /// /// \param init If non-null and there is an explicit \c self.init or /// \c super.init within the body, will be set to point at that /// initializer. BodyInitKind getDelegatingOrChainedInitKind(DiagnosticEngine *diags, ApplyExpr **init = nullptr); /// Whether this constructor is required. bool isRequired() const { return getAttrs().hasAttribute(); } /// Whether this is a complete object initializer. bool isCompleteObjectInit() const { return ConstructorDeclBits.CompleteObjectInit; } /// Set whether this is a complete object initializer. void setCompleteObjectInit(bool completeObjectInit) { ConstructorDeclBits.CompleteObjectInit = completeObjectInit; } /// Whether this is a subobject initializer. bool isSubobjectInit() const { return !isCompleteObjectInit(); } /// Whether the implementation of this method is a stub that traps at runtime. bool hasStubImplementation() const { return ConstructorDeclBits.HasStubImplementation; } /// Set whether the implementation of this method is a stub that /// traps at runtime. void setStubImplementation(bool stub) { ConstructorDeclBits.HasStubImplementation = stub; } ConstructorDecl *getOverriddenDecl() const { return OverriddenDecl; } void setOverriddenDecl(ConstructorDecl *over) { OverriddenDecl = over; } static bool classof(const Decl *D) { return D->getKind() == DeclKind::Constructor; } static bool classof(const AbstractFunctionDecl *D) { return classof(static_cast(D)); } static bool classof(const DeclContext *DC) { if (auto fn = dyn_cast(DC)) return classof(fn); return false; } }; /// DestructorDecl - Declares a destructor for a type. For example: /// /// \code /// struct X { /// var fd : Int /// deinit { /// close(fd) /// } /// } /// \endcode class DestructorDecl : public AbstractFunctionDecl { friend class AbstractFunctionDecl; Pattern *SelfPattern; public: DestructorDecl(Identifier NameHack, SourceLoc DestructorLoc, Pattern *SelfPattern, DeclContext *Parent); void setSelfPattern(Pattern *selfPattern); SourceLoc getDestructorLoc() const { return getNameLoc(); } SourceLoc getStartLoc() const { return getDestructorLoc(); } SourceRange getSourceRange() const; /// Retrieve the Objective-C selector associated with the destructor. /// /// This is always "dealloc". StringRef getObjCSelector(SmallVectorImpl &buffer) const; static bool classof(const Decl *D) { return D->getKind() == DeclKind::Destructor; } static bool classof(const AbstractFunctionDecl *D) { return classof(static_cast(D)); } static bool classof(const DeclContext *DC) { if (auto fn = dyn_cast(DC)) return classof(fn); return false; } }; /// 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(DeclContext *UseDC) const { if (auto vd = dyn_cast(this)) { return vd->isSettable(UseDC); } else if (auto sd = dyn_cast(this)) { return sd->isSettable(); } else return false; } inline bool NominalTypeDecl::isStoredProperty(VarDecl *vd) { return !vd->isStatic() && vd->hasStorage(); } inline MutableArrayRef AbstractFunctionDecl::getArgParamBuffer() { unsigned NumPatterns = AbstractFunctionDeclBits.NumParamPatterns; Pattern **Ptr; switch (getKind()) { default: llvm_unreachable("Unknown AbstractFunctionDecl!"); case DeclKind::Constructor: Ptr = cast(this)->ArgParams; break; case DeclKind::Destructor: Ptr = &cast(this)->SelfPattern; break; case DeclKind::Func: // Argument patterns are tail allocated. Ptr = reinterpret_cast(cast(this) + 1); break; } return MutableArrayRef(Ptr, NumPatterns); } inline MutableArrayRef AbstractFunctionDecl::getBodyParamBuffer() { unsigned NumPatterns = AbstractFunctionDeclBits.NumParamPatterns; Pattern **Ptr; switch (getKind()) { default: llvm_unreachable("Unknown AbstractFunctionDecl!"); case DeclKind::Constructor: Ptr = cast(this)->BodyParams; break; case DeclKind::Destructor: Ptr = &cast(this)->SelfPattern; break; case DeclKind::Func: // Argument patterns are tail allocated. Ptr = reinterpret_cast(cast(this) + 1) + NumPatterns; break; } return MutableArrayRef(Ptr, NumPatterns); } } // end namespace swift #endif