| //===--- Initializer.h - Initializer DeclContext ----------------*- C++ -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See https://swift.org/LICENSE.txt for license information |
| // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines the Initializer class, which is a kind of |
| // DeclContext used for expressions that are not part of a normal |
| // code-evaluation context, such as a global initializer or a default |
| // argument. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef SWIFT_INITIALIZER_H |
| #define SWIFT_INITIALIZER_H |
| |
| #include "swift/AST/DeclContext.h" |
| #include "swift/AST/Decl.h" |
| |
| namespace swift { |
| class PatternBindingDecl; |
| |
| enum class InitializerKind : uint8_t { |
| /// The initializer expression of a PatternBindingDecl that declares |
| /// a global variable or type member. |
| PatternBinding, |
| |
| /// A function's default argument expression. |
| DefaultArgument, |
| }; |
| |
| /// An Initializer is a kind of DeclContext used for expressions that |
| /// aren't potentially evaluated as part of some function. |
| /// |
| /// Generally, Initializers are created lazily, as most initializers |
| /// don't really require DeclContexts. |
| class Initializer : public DeclContext { |
| unsigned Kind : 1; |
| protected: |
| unsigned SpareBits : 31; |
| |
| Initializer(InitializerKind kind, DeclContext *parent) |
| : DeclContext(DeclContextKind::Initializer, parent), |
| Kind(unsigned(kind)) { |
| } |
| |
| // Expose this to subclasses. |
| using DeclContext::setParent; |
| |
| public: |
| /// Returns the kind of initializer this is. |
| InitializerKind getInitializerKind() const { |
| return InitializerKind(Kind); |
| } |
| |
| static bool classof(const DeclContext *DC) { |
| return DC->getContextKind() == DeclContextKind::Initializer; |
| } |
| static bool classof(const Initializer *I) { return true; } |
| }; |
| |
| /// The initializer expression of a non-local pattern binding |
| /// declaration, such as a field or global variable. |
| class PatternBindingInitializer : public Initializer { |
| PatternBindingDecl *Binding; |
| |
| // created lazily for 'self' lookup from lazy property initializer |
| ParamDecl *SelfParam; |
| |
| friend class ASTContext; // calls reset on unused contexts |
| |
| void reset(DeclContext *parent) { |
| setParent(parent); |
| Binding = nullptr; |
| SelfParam = nullptr; |
| } |
| |
| public: |
| explicit PatternBindingInitializer(DeclContext *parent) |
| : Initializer(InitializerKind::PatternBinding, parent), |
| Binding(nullptr), SelfParam(nullptr) { |
| SpareBits = 0; |
| } |
| |
| |
| void setBinding(PatternBindingDecl *binding, unsigned bindingIndex) { |
| setParent(binding->getDeclContext()); |
| Binding = binding; |
| SpareBits = bindingIndex; |
| } |
| |
| PatternBindingDecl *getBinding() const { return Binding; } |
| |
| unsigned getBindingIndex() const { return SpareBits; } |
| |
| /// If this initializes a single @lazy variable, return it. |
| VarDecl *getInitializedLazyVar() const; |
| |
| /// If this initializes a single @lazy variable, lazily create a self |
| /// declaration for it to refer to. |
| ParamDecl *getImplicitSelfDecl() const; |
| |
| static bool classof(const DeclContext *DC) { |
| if (auto init = dyn_cast<Initializer>(DC)) |
| return classof(init); |
| return false; |
| } |
| static bool classof(const Initializer *I) { |
| return I->getInitializerKind() == InitializerKind::PatternBinding; |
| } |
| }; |
| |
| /// SerializedPatternBindingInitializer - This represents what was originally a |
| /// PatternBindingInitializer during serialization. It is preserved as a special |
| /// class only to maintain the correct AST structure and remangling after |
| /// deserialization. |
| class SerializedPatternBindingInitializer : public SerializedLocalDeclContext { |
| PatternBindingDecl *Binding; |
| |
| public: |
| SerializedPatternBindingInitializer(PatternBindingDecl *Binding, |
| unsigned bindingIndex) |
| : SerializedLocalDeclContext(LocalDeclContextKind::PatternBindingInitializer, |
| Binding->getDeclContext()), |
| Binding(Binding) { |
| SpareBits = bindingIndex; |
| } |
| |
| PatternBindingDecl *getBinding() const { |
| return Binding; |
| } |
| |
| unsigned getBindingIndex() const { return SpareBits; } |
| |
| |
| static bool classof(const DeclContext *DC) { |
| if (auto LDC = dyn_cast<SerializedLocalDeclContext>(DC)) |
| return LDC->getLocalDeclContextKind() == |
| LocalDeclContextKind::PatternBindingInitializer; |
| return false; |
| } |
| }; |
| |
| /// A default argument expression. The parent context is the function |
| /// (possibly a closure) for which this is a default argument. |
| class DefaultArgumentInitializer : public Initializer { |
| public: |
| explicit DefaultArgumentInitializer(DeclContext *parent, unsigned index) |
| : Initializer(InitializerKind::DefaultArgument, parent) { |
| SpareBits = index; |
| } |
| |
| unsigned getIndex() const { return SpareBits; } |
| |
| /// Change the parent of this context. This is necessary because |
| /// the function signature is parsed before the function |
| /// declaration/expression itself is built. |
| void changeFunction(DeclContext *parent, ParameterList *paramLists); |
| |
| static bool classof(const DeclContext *DC) { |
| if (auto init = dyn_cast<Initializer>(DC)) |
| return classof(init); |
| return false; |
| } |
| static bool classof(const Initializer *I) { |
| return I->getInitializerKind() == InitializerKind::DefaultArgument; |
| } |
| }; |
| |
| /// SerializedDefaultArgumentInitializer - This represents what was originally a |
| /// DefaultArgumentInitializer during serialization. It is preserved only to |
| /// maintain the correct AST structure and remangling after deserialization. |
| class SerializedDefaultArgumentInitializer : public SerializedLocalDeclContext { |
| const unsigned Index; |
| public: |
| SerializedDefaultArgumentInitializer(unsigned Index, DeclContext *Parent) |
| : SerializedLocalDeclContext(LocalDeclContextKind::DefaultArgumentInitializer, |
| Parent), |
| Index(Index) {} |
| |
| unsigned getIndex() const { |
| return Index; |
| } |
| |
| static bool classof(const DeclContext *DC) { |
| if (auto LDC = dyn_cast<SerializedLocalDeclContext>(DC)) |
| return LDC->getLocalDeclContextKind() == |
| LocalDeclContextKind::DefaultArgumentInitializer; |
| return false; |
| } |
| }; |
| |
| } // end namespace swift |
| |
| #endif |