Skip to content

Commit b7b814d

Browse files
committed
IRGen: Factor out LegacyLayoutFormat.h and add a descriptive comment
1 parent 4ba96f2 commit b7b814d

File tree

2 files changed

+105
-40
lines changed

2 files changed

+105
-40
lines changed

lib/IRGen/LegacyLayoutFormat.h

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
//===--- LegacyLayoutFormat.h - YAML format for legacy layout ---*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the YAML format for the backward deployment type layout
14+
// dump.
15+
//
16+
// When a class with @objc ancestry is statically visible to Clang code, older
17+
// Objective-C runtimes do not give us the opportunity to run any code to
18+
// initialize the class metadata when it is realized.
19+
//
20+
// This creates a problem if the class has resiliently-sized fields. Since the
21+
// standard library and overlays are now built with resilience enabled, this
22+
// creates a backward-compatibility issue where such class definitions would now
23+
// require singleton metadata initialization instead of idempotent metadata
24+
// initialization, and singleton metadata initializaiton precludes the class
25+
// from being statically visible to Clang.
26+
//
27+
// To support this case, we emit fixed metadata for any such class, and in place
28+
// of each resilient field type, we use previously-emitted fixed type info.
29+
//
30+
// This fixed type info must match the Swift standard library and overlays used
31+
// for backward deployment, since on older Objective-C runtimes these layouts
32+
// will be used at runtime.
33+
//
34+
// However, since these types are resilient, their layouts might change in the
35+
// future. Newer Objective-C runtimes will expose a hook allowing the Swift
36+
// runtime to re-compute the class layout when the class is realized.
37+
//
38+
// Note that except for metadata emission, field accesses and instance
39+
// allocation for such classes must proceed as if they use singleton metadata
40+
// initialization, loading the field offsets from global variables and loading
41+
// the size and alignment dynamically from metadata when allocating.
42+
//
43+
// Also, any Swift-side accesses of the metadata must call the metadata accessor
44+
// function, allowing the Swift runtime to re-initialize the layout if
45+
// necessary.
46+
//
47+
//===----------------------------------------------------------------------===//
48+
49+
#ifndef SWIFT_IRGEN_LEGACY_LAYOUT_FORMAT_H
50+
#define SWIFT_IRGEN_LEGACY_LAYOUT_FORMAT_H
51+
52+
#include "llvm/ADT/ArrayRef.h"
53+
#include "llvm/ADT/SmallVector.h"
54+
#include "llvm/Support/FileSystem.h"
55+
#include "llvm/Support/YAMLTraits.h"
56+
#include "llvm/Support/raw_ostream.h"
57+
58+
namespace swift {
59+
namespace irgen {
60+
61+
struct YAMLTypeInfoNode {
62+
std::string Name;
63+
uint64_t Size;
64+
uint64_t Alignment;
65+
uint64_t NumExtraInhabitants;
66+
67+
bool operator<(const YAMLTypeInfoNode &other) const {
68+
return Name < other.Name;
69+
}
70+
};
71+
72+
struct YAMLModuleNode {
73+
StringRef Name;
74+
std::vector<YAMLTypeInfoNode> Decls;
75+
};
76+
77+
} // namespace irgen
78+
} // namespace swift
79+
80+
namespace llvm {
81+
namespace yaml {
82+
83+
template <> struct MappingTraits<swift::irgen::YAMLTypeInfoNode> {
84+
static void mapping(IO &io, swift::irgen::YAMLTypeInfoNode &node) {
85+
io.mapRequired("Name", node.Name);
86+
io.mapRequired("Size", node.Size);
87+
io.mapRequired("Alignment", node.Alignment);
88+
io.mapRequired("ExtraInhabitants", node.NumExtraInhabitants);
89+
}
90+
};
91+
92+
template <> struct MappingTraits<swift::irgen::YAMLModuleNode> {
93+
static void mapping(IO &io, swift::irgen::YAMLModuleNode &node) {
94+
io.mapRequired("Name", node.Name);
95+
io.mapOptional("Decls", node.Decls);
96+
}
97+
};
98+
99+
} // namespace yaml
100+
} // namespace llvm
101+
102+
LLVM_YAML_IS_SEQUENCE_VECTOR(swift::irgen::YAMLTypeInfoNode);
103+
104+
#endif // SWIFT_IRGEN_LEGACY_LAYOUT_FORMAT_H

lib/IRGen/TypeLayoutDumper.cpp

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "GenType.h"
2121
#include "IRGen.h"
2222
#include "IRGenModule.h"
23+
#include "LegacyLayoutFormat.h"
2324

2425
#include "swift/AST/ASTContext.h"
2526
#include "swift/AST/ASTMangler.h"
@@ -58,48 +59,8 @@ class NominalTypeWalker : public ASTWalker {
5859
}
5960
};
6061

61-
struct YAMLTypeInfoNode {
62-
std::string Name;
63-
uint64_t Size;
64-
uint64_t Alignment;
65-
uint64_t NumExtraInhabitants;
66-
67-
bool operator<(const YAMLTypeInfoNode &other) const {
68-
return Name < other.Name;
69-
}
70-
};
71-
72-
struct YAMLModuleNode {
73-
StringRef Name;
74-
std::vector<YAMLTypeInfoNode> Decls;
75-
};
76-
7762
} // end anonymous namespace
7863

79-
namespace llvm {
80-
namespace yaml {
81-
82-
template <> struct MappingTraits<YAMLTypeInfoNode> {
83-
static void mapping(IO &io, YAMLTypeInfoNode &node) {
84-
io.mapRequired("Name", node.Name);
85-
io.mapRequired("Size", node.Size);
86-
io.mapRequired("Alignment", node.Alignment);
87-
io.mapRequired("ExtraInhabitants", node.NumExtraInhabitants);
88-
}
89-
};
90-
91-
template <> struct MappingTraits<YAMLModuleNode> {
92-
static void mapping(IO &io, YAMLModuleNode &node) {
93-
io.mapRequired("Name", node.Name);
94-
io.mapOptional("Decls", node.Decls);
95-
}
96-
};
97-
98-
} // namespace yaml
99-
} // namespace llvm
100-
101-
LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLTypeInfoNode);
102-
10364
static std::string mangleTypeAsContext(const NominalTypeDecl *type) {
10465
Mangle::ASTMangler Mangler;
10566
return Mangler.mangleTypeAsContextUSR(type);

0 commit comments

Comments
 (0)