From e3033c0ce5517efddbf92a079ad1e0ca4868591f Mon Sep 17 00:00:00 2001 From: Puyan Lotfi Date: Sat, 28 Mar 2020 04:08:27 -0400 Subject: [llvm][clang][IFS] Enhancing the llvm-ifs yaml format for symbol lists. Prior to this change the clang interface stubs format resembled something ending with a symbol list like this: Symbols: a: { Type: Func } This was problematic because we didn't actually want a map format and also because we didn't like that an empty symbol list required "Symbols: {}". That is to say without the empty {} llvm-ifs would crash on an empty list. With this new format it is much more clear which field is the symbol name, and instead the [] that is used to express an empty symbol vector is optional, ie: Symbols: - { Name: a, Type: Func } or Symbols: [] or Symbols: This further diverges the format from existing llvm-elftapi. This is a good thing because although the format originally came from the same place, they are not the same in any way. Differential Revision: https://reviews.llvm.org/D76979 --- llvm/tools/llvm-ifs/llvm-ifs.cpp | 41 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'llvm/tools/llvm-ifs/llvm-ifs.cpp') diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp index 3b0d2ee..0d1a751 100644 --- a/llvm/tools/llvm-ifs/llvm-ifs.cpp +++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -26,6 +26,7 @@ #include "llvm/TextAPI/MachO/TextAPIWriter.h" #include #include +#include using namespace llvm; using namespace llvm::yaml; @@ -34,8 +35,8 @@ using namespace llvm::MachO; #define DEBUG_TYPE "llvm-ifs" namespace { -const VersionTuple IFSVersionCurrent(1, 2); -} +const VersionTuple IFSVersionCurrent(2, 0); +} // end anonymous namespace static cl::opt Action("action", cl::desc(""), cl::value_desc("write-ifs | write-bin"), @@ -76,6 +77,7 @@ std::string getTypeName(IFSSymbolType Type) { } struct IFSSymbol { + IFSSymbol() = default; IFSSymbol(std::string SymbolName) : Name(SymbolName) {} std::string Name; uint64_t Size; @@ -85,6 +87,8 @@ struct IFSSymbol { bool operator<(const IFSSymbol &RHS) const { return Name < RHS.Name; } }; +LLVM_YAML_IS_SEQUENCE_VECTOR(IFSSymbol) + namespace llvm { namespace yaml { /// YAML traits for IFSSymbolType. @@ -124,6 +128,7 @@ template <> struct ScalarTraits { /// YAML traits for IFSSymbol. template <> struct MappingTraits { static void mapping(IO &IO, IFSSymbol &Symbol) { + IO.mapRequired("Name", Symbol.Name); IO.mapRequired("Type", Symbol.Type); // The need for symbol size depends on the symbol type. if (Symbol.Type == IFSSymbolType::NoType) @@ -140,20 +145,6 @@ template <> struct MappingTraits { static const bool flow = true; }; -/// YAML traits for set of IFSSymbols. -template <> struct CustomMappingTraits> { - static void inputOne(IO &IO, StringRef Key, std::set &Set) { - std::string Name = Key.str(); - IFSSymbol Sym(Name); - IO.mapRequired(Name.c_str(), Sym); - Set.insert(Sym); - } - - static void output(IO &IO, std::set &Set) { - for (auto &Sym : Set) - IO.mapRequired(Sym.Name.c_str(), const_cast(Sym)); - } -}; } // namespace yaml } // namespace llvm @@ -167,7 +158,7 @@ public: std::string ObjectFileFormat; Optional SOName; std::vector NeededLibs; - std::set Symbols; + std::vector Symbols; IFSStub() = default; IFSStub(const IFSStub &Stub) @@ -186,14 +177,18 @@ namespace yaml { /// YAML traits for IFSStub objects. template <> struct MappingTraits { static void mapping(IO &IO, IFSStub &Stub) { - if (!IO.mapTag("!experimental-ifs-v1", true)) + if (!IO.mapTag("!experimental-ifs-v2", true)) IO.setError("Not a .ifs YAML file."); + + auto OldContext = IO.getContext(); + IO.setContext(&Stub); IO.mapRequired("IfsVersion", Stub.IfsVersion); IO.mapOptional("Triple", Stub.Triple); IO.mapOptional("ObjectFileFormat", Stub.ObjectFileFormat); IO.mapOptional("SOName", Stub.SOName); IO.mapOptional("NeededLibs", Stub.NeededLibs); IO.mapRequired("Symbols", Stub.Symbols); + IO.setContext(&OldContext); } }; } // namespace yaml @@ -218,7 +213,7 @@ static Expected> readInputFile(StringRef FilePath) { return std::move(Stub); } -int writeTbdStub(const llvm::Triple &T, const std::set &Symbols, +int writeTbdStub(const llvm::Triple &T, const std::vector &Symbols, const StringRef Format, raw_ostream &Out) { auto PlatformKindOrError = @@ -280,7 +275,7 @@ int writeTbdStub(const llvm::Triple &T, const std::set &Symbols, return 0; } -int writeElfStub(const llvm::Triple &T, const std::set &Symbols, +int writeElfStub(const llvm::Triple &T, const std::vector &Symbols, const StringRef Format, raw_ostream &Out) { SmallString<0> Storage; Storage.clear(); @@ -387,8 +382,8 @@ int writeIfso(const IFSStub &Stub, bool IsWriteIfs, raw_ostream &Out) { // TODO: Drop ObjectFileFormat, it can be subsumed from the triple. // New Interface Stubs Yaml Format: -// --- !experimental-ifs-v1 -// IfsVersion: 1.0 +// --- !experimental-ifs-v2 +// IfsVersion: 2.0 // Triple: // ObjectFileFormat: // Symbols: @@ -517,7 +512,7 @@ int main(int argc, char *argv[]) { } for (auto &Entry : SymbolMap) - Stub.Symbols.insert(Entry.second); + Stub.Symbols.push_back(Entry.second); std::error_code SysErr; -- cgit v1.1