| //===--- LegacyLayoutFormat.h - YAML format for legacy layout ---*- 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 YAML format for the backward deployment type layout |
| // dump. |
| // |
| // When a class with @objc ancestry is statically visible to Clang code, older |
| // Objective-C runtimes do not give us the opportunity to run any code to |
| // initialize the class metadata when it is realized. |
| // |
| // This creates a problem if the class has resiliently-sized fields. Since the |
| // standard library and overlays are now built with resilience enabled, this |
| // creates a backward-compatibility issue where such class definitions would now |
| // require singleton metadata initialization instead of idempotent metadata |
| // initialization, and singleton metadata initializaiton precludes the class |
| // from being statically visible to Clang. |
| // |
| // To support this case, we emit fixed metadata for any such class, and in place |
| // of each resilient field type, we use previously-emitted fixed type info. |
| // |
| // This fixed type info must match the Swift standard library and overlays used |
| // for backward deployment, since on older Objective-C runtimes these layouts |
| // will be used at runtime. |
| // |
| // However, since these types are resilient, their layouts might change in the |
| // future. Newer Objective-C runtimes will expose a hook allowing the Swift |
| // runtime to re-compute the class layout when the class is realized. |
| // |
| // Note that except for metadata emission, field accesses and instance |
| // allocation for such classes must proceed as if they use singleton metadata |
| // initialization, loading the field offsets from global variables and loading |
| // the size and alignment dynamically from metadata when allocating. |
| // |
| // Also, any Swift-side accesses of the metadata must call the metadata accessor |
| // function, allowing the Swift runtime to re-initialize the layout if |
| // necessary. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef SWIFT_IRGEN_LEGACY_LAYOUT_FORMAT_H |
| #define SWIFT_IRGEN_LEGACY_LAYOUT_FORMAT_H |
| |
| #include "llvm/ADT/ArrayRef.h" |
| #include "llvm/ADT/SmallVector.h" |
| #include "llvm/Support/FileSystem.h" |
| #include "llvm/Support/YAMLTraits.h" |
| #include "llvm/Support/raw_ostream.h" |
| |
| namespace swift { |
| namespace irgen { |
| |
| struct YAMLTypeInfoNode { |
| std::string Name; |
| uint64_t Size; |
| uint64_t Alignment; |
| uint64_t NumExtraInhabitants; |
| |
| bool operator<(const YAMLTypeInfoNode &other) const { |
| return Name < other.Name; |
| } |
| }; |
| |
| struct YAMLModuleNode { |
| StringRef Name; |
| std::vector<YAMLTypeInfoNode> Decls; |
| }; |
| |
| } // namespace irgen |
| } // namespace swift |
| |
| namespace llvm { |
| namespace yaml { |
| |
| template <> struct MappingTraits<swift::irgen::YAMLTypeInfoNode> { |
| static void mapping(IO &io, swift::irgen::YAMLTypeInfoNode &node) { |
| io.mapRequired("Name", node.Name); |
| io.mapRequired("Size", node.Size); |
| io.mapRequired("Alignment", node.Alignment); |
| io.mapRequired("ExtraInhabitants", node.NumExtraInhabitants); |
| } |
| }; |
| |
| template <> struct MappingTraits<swift::irgen::YAMLModuleNode> { |
| static void mapping(IO &io, swift::irgen::YAMLModuleNode &node) { |
| io.mapRequired("Name", node.Name); |
| io.mapOptional("Decls", node.Decls); |
| } |
| }; |
| |
| } // namespace yaml |
| } // namespace llvm |
| |
| LLVM_YAML_IS_SEQUENCE_VECTOR(swift::irgen::YAMLTypeInfoNode); |
| LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(swift::irgen::YAMLModuleNode); |
| |
| #endif // SWIFT_IRGEN_LEGACY_LAYOUT_FORMAT_H |