Skip to content

[GOFF] Refactor writing GOFF records #93855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 74 additions & 12 deletions llvm/include/llvm/ObjectYAML/GOFFYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,87 @@ namespace llvm {
// to use yaml::IO, we use these structures which are closer to the source.
namespace GOFFYAML {

struct FileHeader {
uint32_t TargetEnvironment = 0;
uint32_t TargetOperatingSystem = 0;
uint16_t CCSID = 0;
StringRef CharacterSetName;
StringRef LanguageProductIdentifier;
uint32_t ArchitectureLevel = 0;
std::optional<uint16_t> InternalCCSID;
std::optional<uint8_t> TargetSoftwareEnvironment;
LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_AMODE)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, GOFF_ENDFLAGS)

// The GOFF format uses different kinds of logical records. The format imposes
// some rules on those records (e.g. the module header must come first, no
// forward references to records, etc.). However, to be able to specify invalid
// GOFF files, we treat all records the same way.
struct RecordBase {
enum class Kind {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you just use the RecordType enum from llvm/BinaryFormat/GOFF.h here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are currently the same, but I do not think that it is good to couple the record type with the class hierarchy discriminator. E.g. in C++ I could model a relocation entry as a record, and treat it as a sub-record of the relocation directory. I currently do not do this, but coupling the discriminator to the record type would be the design decision that I will never do that, which seems a bit limiting to me.

ModuleHeader,
RelocationDirectory,
Symbol,
Text,
DeferredLength,
EndOfModule
};

private:
const Kind RecordKind;

protected:
RecordBase(Kind RecordKind) : RecordKind(RecordKind) {}

public:
Kind getKind() const { return RecordKind; }
};
using RecordPtr = std::unique_ptr<RecordBase>;

struct ModuleHeader : public RecordBase {
ModuleHeader() : RecordBase(Kind::ModuleHeader) {}

uint32_t ArchitectureLevel;
uint16_t PropertiesLength;
std::optional<yaml::BinaryRef> Properties;

static bool classof(const RecordBase *S) {
return S->getKind() == Kind::ModuleHeader;
}
};

struct EndOfModule : public RecordBase {
EndOfModule() : RecordBase(Kind::EndOfModule) {}

GOFF_ENDFLAGS Flags;
GOFF_AMODE AMODE;
uint32_t RecordCount;
uint32_t ESDID;
uint32_t Offset;
uint16_t NameLength;
StringRef EntryName;

static bool classof(const RecordBase *S) {
return S->getKind() == Kind::EndOfModule;
}
};

struct Object {
FileHeader Header;
Object();
// A GOFF file is a sequence of records.
std::vector<RecordPtr> Records;
};
} // end namespace GOFFYAML
} // end namespace llvm

LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::FileHeader)
LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_AMODE)
LLVM_YAML_DECLARE_ENUM_TRAITS(GOFFYAML::GOFF_ENDFLAGS)

LLVM_YAML_IS_SEQUENCE_VECTOR(GOFFYAML::RecordPtr)
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::RecordPtr)

LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::ModuleHeader)
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::EndOfModule)
LLVM_YAML_DECLARE_MAPPING_TRAITS(GOFFYAML::Object)

namespace llvm {
namespace yaml {

template <> struct CustomMappingTraits<GOFFYAML::RecordPtr> {
static void inputOne(IO &IO, StringRef Key, GOFFYAML::RecordPtr &Elem);
static void output(IO &IO, GOFFYAML::RecordPtr &Elem);
};

} // namespace yaml
} // namespace llvm
#endif // LLVM_OBJECTYAML_GOFFYAML_H
Loading
Loading