//===--- CodeSynthesis.h - Typechecker code synthesis -----------*- 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 a typechecker-internal interface to a bunch of // routines for synthesizing various declarations. // //===----------------------------------------------------------------------===// #ifndef SWIFT_TYPECHECKING_CODESYNTHESIS_H #define SWIFT_TYPECHECKING_CODESYNTHESIS_H #include "TypeCheckObjC.h" #include "swift/AST/ForeignErrorConvention.h" #include "swift/Basic/ExternalUnion.h" #include "swift/Basic/LLVM.h" #include "llvm/ADT/Optional.h" namespace swift { class AbstractFunctionDecl; class AbstractStorageDecl; class ASTContext; class ClassDecl; class ConstructorDecl; class FuncDecl; class GenericParamList; class NominalTypeDecl; class Type; class ValueDecl; class VarDecl; class TypeChecker; class ObjCReason; /// A function which needs to have its body synthesized. /// /// This class exists in expectation that someone will need to add more /// information to it. class SynthesizedFunction { public: enum Kind { Getter, Setter, ReadCoroutine, ModifyCoroutine, LazyGetter, LazySetter, }; private: FuncDecl *Fn; Kind K; using Members = ExternalUnionMembers; static Members::Index getIndexForKind(Kind kind) { switch (kind) { case Kind::Getter: case Kind::Setter: case Kind::ReadCoroutine: case Kind::ModifyCoroutine: return Members::indexOf(); case Kind::LazyGetter: case Kind::LazySetter: return Members::indexOf(); } llvm_unreachable("bad kind"); }; ExternalUnion Extra; static_assert(decltype(Extra)::union_is_trivially_copyable, "expected all members to be trivial"); public: SynthesizedFunction(FuncDecl *fn, Kind kind) : Fn(fn), K(kind) { assert(getIndexForKind(kind) == Members::indexOf() && "this storage kind requires extra data"); } SynthesizedFunction(FuncDecl *fn, Kind kind, VarDecl *var) : Fn(fn), K(kind) { Extra.emplace(K, var); } FuncDecl *getDecl() const { return Fn; } Kind getKind() const { return K; } VarDecl *getLazyTargetVariable() const { return Extra.get(K); } }; // These are implemented in TypeCheckDecl.cpp. void makeFinal(ASTContext &ctx, ValueDecl *D); // Implemented in TypeCheckerOverride.cpp bool checkOverrides(ValueDecl *decl); // These are implemented in CodeSynthesis.cpp. void maybeAddAccessorsToStorage(TypeChecker &TC, AbstractStorageDecl *storage); void triggerAccessorSynthesis(TypeChecker &TC, AbstractStorageDecl *storage); /// \brief Describes the kind of implicit constructor that will be /// generated. enum class ImplicitConstructorKind { /// \brief The default constructor, which default-initializes each /// of the instance variables. Default, /// \brief The memberwise constructor, which initializes each of /// the instance variables from a parameter of the same type and /// name. Memberwise }; /// \brief Create an implicit struct or class constructor. /// /// \param decl The struct or class for which a constructor will be created. /// \param ICK The kind of implicit constructor to create. /// /// \returns The newly-created constructor, which has already been type-checked /// (but has not been added to the containing struct or class). ConstructorDecl *createImplicitConstructor(TypeChecker &tc, NominalTypeDecl *decl, ImplicitConstructorKind ICK); /// The kind of designated initializer to synthesize. enum class DesignatedInitKind { /// A stub initializer, which is not visible to name lookup and /// merely aborts at runtime. Stub, /// An initializer that simply chains to the corresponding /// superclass initializer. Chaining }; /// Create a new initializer that overrides the given designated /// initializer. /// /// \param classDecl The subclass in which the new initializer will /// be declared. /// /// \param superclassCtor The superclass initializer for which this /// routine will create an override. /// /// \param kind The kind of initializer to synthesize. /// /// \returns the newly-created initializer that overrides \p /// superclassCtor. ConstructorDecl *createDesignatedInitOverride(TypeChecker &TC, ClassDecl *classDecl, ConstructorDecl *superclassCtor, DesignatedInitKind kind); } // end namespace swift #endif