diff options
author | Puyan Lotfi <puyan@puyan.org> | 2020-03-28 04:08:27 -0400 |
---|---|---|
committer | Puyan Lotfi <puyan@puyan.org> | 2020-04-01 10:49:06 -0400 |
commit | e3033c0ce5517efddbf92a079ad1e0ca4868591f (patch) | |
tree | 98ef0cb8c4d7c7ad93346933371f8a43f600ff79 /llvm/tools/llvm-ifs/llvm-ifs.cpp | |
parent | a67cd71acdb0cd636097a74ec80e2f23ef301ada (diff) | |
download | llvm-e3033c0ce5517efddbf92a079ad1e0ca4868591f.zip llvm-e3033c0ce5517efddbf92a079ad1e0ca4868591f.tar.gz llvm-e3033c0ce5517efddbf92a079ad1e0ca4868591f.tar.bz2 |
[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
Diffstat (limited to 'llvm/tools/llvm-ifs/llvm-ifs.cpp')
-rw-r--r-- | llvm/tools/llvm-ifs/llvm-ifs.cpp | 41 |
1 files changed, 18 insertions, 23 deletions
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 <set> #include <string> +#include <vector> 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<std::string> Action("action", cl::desc("<llvm-ifs action>"), 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<VersionTuple> { /// YAML traits for IFSSymbol. template <> struct MappingTraits<IFSSymbol> { 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<IFSSymbol> { static const bool flow = true; }; -/// YAML traits for set of IFSSymbols. -template <> struct CustomMappingTraits<std::set<IFSSymbol>> { - static void inputOne(IO &IO, StringRef Key, std::set<IFSSymbol> &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<IFSSymbol> &Set) { - for (auto &Sym : Set) - IO.mapRequired(Sym.Name.c_str(), const_cast<IFSSymbol &>(Sym)); - } -}; } // namespace yaml } // namespace llvm @@ -167,7 +158,7 @@ public: std::string ObjectFileFormat; Optional<std::string> SOName; std::vector<std::string> NeededLibs; - std::set<IFSSymbol> Symbols; + std::vector<IFSSymbol> Symbols; IFSStub() = default; IFSStub(const IFSStub &Stub) @@ -186,14 +177,18 @@ namespace yaml { /// YAML traits for IFSStub objects. template <> struct MappingTraits<IFSStub> { 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<std::unique_ptr<IFSStub>> readInputFile(StringRef FilePath) { return std::move(Stub); } -int writeTbdStub(const llvm::Triple &T, const std::set<IFSSymbol> &Symbols, +int writeTbdStub(const llvm::Triple &T, const std::vector<IFSSymbol> &Symbols, const StringRef Format, raw_ostream &Out) { auto PlatformKindOrError = @@ -280,7 +275,7 @@ int writeTbdStub(const llvm::Triple &T, const std::set<IFSSymbol> &Symbols, return 0; } -int writeElfStub(const llvm::Triple &T, const std::set<IFSSymbol> &Symbols, +int writeElfStub(const llvm::Triple &T, const std::vector<IFSSymbol> &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: <llvm triple> // ObjectFileFormat: <ELF | others not yet supported> // 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; |