From: Simon Atanasyan Date: Fri, 23 May 2014 08:07:09 +0000 (+0000) Subject: [YAML] Add an optional argument `EnumMask` to the `yaml::IO::bitSetCase()`. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=84a0dc323d90f86e899519b31b789ed5c0a0ec9a;p=oota-llvm.git [YAML] Add an optional argument `EnumMask` to the `yaml::IO::bitSetCase()`. Some bit-set fields used in ELF file headers in fact contain two parts. The first one is a regular bit-field. The second one is an enumeraion. For example ELF header `e_flags` for MIPS target might contain the following values: Bit-set values: EF_MIPS_NOREORDER = 0x00000001 EF_MIPS_PIC = 0x00000002 EF_MIPS_CPIC = 0x00000004 EF_MIPS_ABI2 = 0x00000020 Enumeration: EF_MIPS_ARCH_32 = 0x50000000 EF_MIPS_ARCH_64 = 0x60000000 EF_MIPS_ARCH_32R2 = 0x70000000 EF_MIPS_ARCH_64R2 = 0x80000000 For printing bit-sets we use the `yaml::IO::bitSetCase()`. It does not support bit-set/enumeration combinations and prints too many flags from an enumeration part. This patch fixes this problem. New method `yaml::IO::maskedBitSetCase()` handle "enumeration" part of bitset defined by provided mask. Patch reviewed by Nick Kledzik and Sean Silva. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209504 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/YamlIO.rst b/docs/YamlIO.rst index dfb348da2f4..76dd021f82f 100644 --- a/docs/YamlIO.rst +++ b/docs/YamlIO.rst @@ -399,6 +399,42 @@ the above schema, a same valid YAML document is: name: Tom flags: [ pointy, flat ] +Sometimes a "flags" field might contains an enumeration part +defined by a bit-mask. + +.. code-block:: c++ + + enum { + flagsFeatureA = 1, + flagsFeatureB = 2, + flagsFeatureC = 4, + + flagsCPUMask = 24, + + flagsCPU1 = 8, + flagsCPU2 = 16 + }; + +To support reading and writing such fields, you need to use the maskedBitSet() +method and provide the bit values, their names and the enumeration mask. + +.. code-block:: c++ + + template <> + struct ScalarBitSetTraits { + static void bitset(IO &io, MyFlags &value) { + io.bitSetCase(value, "featureA", flagsFeatureA); + io.bitSetCase(value, "featureB", flagsFeatureB); + io.bitSetCase(value, "featureC", flagsFeatureC); + io.maskedBitSetCase(value, "CPU1", flagsCPU1, flagsCPUMask); + io.maskedBitSetCase(value, "CPU2", flagsCPU2, flagsCPUMask); + } + }; + +YAML I/O (when writing) will apply the enumeration mask to the flags field, +and compare the result and values from the bitset. As in case of a regular +bitset, each that matches will cause the corresponding string to be added +to the flow sequence. Custom Scalar ------------- diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index 7f4a9229354..4ee05ed1335 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -487,6 +487,19 @@ public: } } + template + void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) { + if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal)) + Val = Val | ConstVal; + } + + template + void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal, + uint32_t Mask) { + if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal)) + Val = Val | ConstVal; + } + void *getContext(); void setContext(void *); diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp index 8329853340c..7d50f23417b 100644 --- a/lib/Object/ELFYAML.cpp +++ b/lib/Object/ELFYAML.cpp @@ -246,16 +246,17 @@ void ScalarBitSetTraits::bitset(IO &IO, const auto *Object = static_cast(IO.getContext()); assert(Object && "The IO context is not initialized"); #define BCase(X) IO.bitSetCase(Value, #X, ELF::X); +#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M); switch (Object->Header.Machine) { case ELF::EM_ARM: BCase(EF_ARM_SOFT_FLOAT) BCase(EF_ARM_VFP_FLOAT) - BCase(EF_ARM_EABI_UNKNOWN) - BCase(EF_ARM_EABI_VER1) - BCase(EF_ARM_EABI_VER2) - BCase(EF_ARM_EABI_VER3) - BCase(EF_ARM_EABI_VER4) - BCase(EF_ARM_EABI_VER5) + BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK) + BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK) + BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK) + BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK) + BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK) + BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK) break; case ELF::EM_MIPS: BCase(EF_MIPS_NOREORDER) @@ -266,17 +267,17 @@ void ScalarBitSetTraits::bitset(IO &IO, BCase(EF_MIPS_ABI_O32) BCase(EF_MIPS_MICROMIPS) BCase(EF_MIPS_ARCH_ASE_M16) - BCase(EF_MIPS_ARCH_1) - BCase(EF_MIPS_ARCH_2) - BCase(EF_MIPS_ARCH_3) - BCase(EF_MIPS_ARCH_4) - BCase(EF_MIPS_ARCH_5) - BCase(EF_MIPS_ARCH_32) - BCase(EF_MIPS_ARCH_64) - BCase(EF_MIPS_ARCH_32R2) - BCase(EF_MIPS_ARCH_64R2) - BCase(EF_MIPS_ARCH_32R6) - BCase(EF_MIPS_ARCH_64R6) + BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH) + BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH) break; case ELF::EM_HEXAGON: BCase(EF_HEXAGON_MACH_V2) @@ -292,6 +293,7 @@ void ScalarBitSetTraits::bitset(IO &IO, llvm_unreachable("Unsupported architecture"); } #undef BCase +#undef BCaseMask } void ScalarEnumerationTraits::enumeration( diff --git a/test/Object/obj2yaml.test b/test/Object/obj2yaml.test index db03f5afa4d..1c1526349fd 100644 --- a/test/Object/obj2yaml.test +++ b/test/Object/obj2yaml.test @@ -191,7 +191,7 @@ ELF-MIPSEL-NEXT: Class: ELFCLASS32 ELF-MIPSEL-NEXT: Data: ELFDATA2LSB ELF-MIPSEL-NEXT: Type: ET_REL ELF-MIPSEL-NEXT: Machine: EM_MIPS -ELF-MIPSEL-NEXT: Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_1, EF_MIPS_ARCH_2, EF_MIPS_ARCH_5, EF_MIPS_ARCH_32 ] +ELF-MIPSEL-NEXT: Flags: [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32 ] ELF-MIPSEL-NEXT: Sections: ELF-MIPSEL-NEXT: - Name: .text ELF-MIPSEL-NEXT: Type: SHT_PROGBITS @@ -285,7 +285,7 @@ ELF-MIPS64EL-NEXT: Class: ELFCLASS64 ELF-MIPS64EL-NEXT: Data: ELFDATA2LSB ELF-MIPS64EL-NEXT: Type: ET_REL ELF-MIPS64EL-NEXT: Machine: EM_MIPS -ELF-MIPS64EL-NEXT: Flags: [ EF_MIPS_ARCH_1, EF_MIPS_ARCH_3 ] +ELF-MIPS64EL-NEXT: Flags: [ EF_MIPS_ARCH_3 ] ELF-MIPS64EL-NEXT: Sections: ELF-MIPS64EL-NEXT: - Name: .text ELF-MIPS64EL-NEXT: Type: SHT_PROGBITS