Skip to content

Commit da97d3d

Browse files
committed
[GOFF] Refactor writing GOFF records
A GOFF file is basically a sequence of records. Change the YAML mapping for GOFF files to reflect this. As result, creating files for testing, e.g. without a module header, becomes possible.
1 parent 1ee02f9 commit da97d3d

File tree

11 files changed

+403
-223
lines changed

11 files changed

+403
-223
lines changed

Diff for: llvm/include/llvm/ObjectYAML/GOFFYAML.h

+74-12
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,87 @@ namespace llvm {
2525
// to use yaml::IO, we use these structures which are closer to the source.
2626
namespace GOFFYAML {
2727

28-
struct FileHeader {
29-
uint32_t TargetEnvironment = 0;
30-
uint32_t TargetOperatingSystem = 0;
31-
uint16_t CCSID = 0;
32-
StringRef CharacterSetName;
33-
StringRef LanguageProductIdentifier;
34-
uint32_t ArchitectureLevel = 0;
35-
std::optional<uint16_t> InternalCCSID;
36-
std::optional<uint8_t> TargetSoftwareEnvironment;
28+
LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_AMODE)
29+
LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ENDFLAGS)
30+
31+
// The GOFF format uses different kinds of logical records. The format imposes
32+
// some rules on those records (e.g. the module header must come first, no
33+
// forward references to records, etc.). However, to be able to specify invalid
34+
// GOFF files, we treat all records the same way.
35+
struct RecordBase {
36+
enum RecordBaseKind {
37+
RBK_ModuleHeader,
38+
RBK_RelocationDirectory,
39+
RBK_Symbol,
40+
RBK_Text,
41+
RBK_DeferredLength,
42+
RBK_EndOfModule
43+
};
44+
45+
private:
46+
const RecordBaseKind Kind;
47+
48+
protected:
49+
RecordBase(RecordBaseKind Kind) : Kind(Kind) {}
50+
51+
public:
52+
RecordBaseKind getKind() const { return Kind; }
53+
};
54+
using RecordPtr = std::unique_ptr<RecordBase>;
55+
56+
struct ModuleHeader : public RecordBase {
57+
ModuleHeader() : RecordBase(RBK_ModuleHeader) {}
58+
59+
uint32_t ArchitectureLevel;
60+
uint16_t PropertiesLength;
61+
std::optional<yaml::BinaryRef> Properties;
62+
63+
static bool classof(const RecordBase *S) {
64+
return S->getKind() == RBK_ModuleHeader;
65+
}
66+
};
67+
68+
struct EndOfModule : public RecordBase {
69+
EndOfModule() : RecordBase(RBK_EndOfModule) {}
70+
71+
GOFF_ENDFLAGS Flags;
72+
GOFF_AMODE AMODE;
73+
uint32_t RecordCount;
74+
uint32_t ESDID;
75+
uint32_t Offset;
76+
uint16_t NameLength;
77+
StringRef EntryName;
78+
79+
static bool classof(const RecordBase *S) {
80+
return S->getKind() == RBK_EndOfModule;
81+
}
3782
};
3883

3984
struct Object {
40-
FileHeader Header;
41-
Object();
85+
// A GOFF file is a sequence of records.
86+
std::vector<RecordPtr> Records;
4287
};
4388
} // end namespace GOFFYAML
4489
} // end namespace llvm
4590

46-
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::FileHeader)
91+
LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_AMODE)
92+
LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ENDFLAGS)
93+
94+
LLVM_YAML_IS_SEQUENCE_VECTOR(GOFFYAML::RecordPtr)
95+
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::RecordPtr)
96+
97+
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::ModuleHeader)
98+
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::EndOfModule)
4799
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::Object)
48100

101+
namespace llvm {
102+
namespace yaml {
103+
104+
template <> struct CustomMappingTraits<GOFFYAML::RecordPtr> {
105+
static void inputOne(IO &IO, StringRef Key, GOFFYAML::RecordPtr &Elem);
106+
static void output(IO &IO, GOFFYAML::RecordPtr &Elem);
107+
};
108+
109+
} // namespace yaml
110+
} // namespace llvm
49111
#endif // LLVM_OBJECTYAML_GOFFYAML_H

0 commit comments

Comments
 (0)