浏览代码

IR: Add helper to split debug info flags bitfield

Split debug info 'flags' bitfield over a vector so the current flags can
be iterated over.  This API (in combination with r230107) will be used
for assembly support for symbolic constants.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@230108 91177308-0d34-0410-b5e6-96231b3b80d8
Duncan P. N. Exon Smith 10 年之前
父节点
当前提交
8629ae24e7
共有 3 个文件被更改,包括 52 次插入0 次删除
  1. 7 0
      include/llvm/IR/DebugInfo.h
  2. 24 0
      lib/IR/DebugInfo.cpp
  3. 21 0
      unittests/IR/DebugInfoTest.cpp

+ 7 - 0
include/llvm/IR/DebugInfo.h

@@ -140,6 +140,13 @@ public:
   static unsigned getFlag(StringRef Flag);
   static const char *getFlagString(unsigned Flag);
 
+  /// \brief Split up a flags bitfield.
+  ///
+  /// Split \c Flags into \c SplitFlags, a vector of its components.  Returns
+  /// any remaining (unrecognized) bits.
+  static unsigned splitFlags(unsigned Flags,
+                             SmallVectorImpl<unsigned> &SplitFlags);
+
 protected:
   const MDNode *DbgNode;
 

+ 24 - 0
lib/IR/DebugInfo.cpp

@@ -55,6 +55,30 @@ const char *DIDescriptor::getFlagString(unsigned Flag) {
   }
 }
 
+unsigned DIDescriptor::splitFlags(unsigned Flags,
+                                  SmallVectorImpl<unsigned> &SplitFlags) {
+  // Accessibility flags need to be specially handled, since they're packed
+  // together.
+  if (unsigned A = Flags & FlagAccessibility) {
+    if (A == FlagPrivate)
+      SplitFlags.push_back(FlagPrivate);
+    else if (A == FlagProtected)
+      SplitFlags.push_back(FlagProtected);
+    else
+      SplitFlags.push_back(FlagPublic);
+    Flags &= ~A;
+  }
+
+#define HANDLE_DI_FLAG(ID, NAME)                                               \
+  if (unsigned Bit = Flags & ID) {                                             \
+    SplitFlags.push_back(Bit);                                                 \
+    Flags &= ~Bit;                                                             \
+  }
+#include "llvm/IR/DebugInfoFlags.def"
+
+  return Flags;
+}
+
 bool DIDescriptor::Verify() const {
   return DbgNode &&
          (DIDerivedType(DbgNode).Verify() ||

+ 21 - 0
unittests/IR/DebugInfoTest.cpp

@@ -111,4 +111,25 @@ TEST(DIDescriptorTest, getFlagString) {
   EXPECT_EQ(StringRef(), DIDescriptor::getFlagString(0xffff));
 }
 
+TEST(DIDescriptorTest, splitFlags) {
+  // Some valid flags.
+#define CHECK_SPLIT(FLAGS, VECTOR, REMAINDER)                                  \
+  {                                                                            \
+    SmallVector<unsigned, 8> V;                                                \
+    EXPECT_EQ(REMAINDER, DIDescriptor::splitFlags(FLAGS, V));                  \
+    EXPECT_TRUE(makeArrayRef(V).equals VECTOR);                                \
+  }
+  CHECK_SPLIT(DIDescriptor::FlagPublic, (DIDescriptor::FlagPublic), 0u);
+  CHECK_SPLIT(DIDescriptor::FlagProtected, (DIDescriptor::FlagProtected), 0u);
+  CHECK_SPLIT(DIDescriptor::FlagPrivate, (DIDescriptor::FlagPrivate), 0u);
+  CHECK_SPLIT(DIDescriptor::FlagVector, (DIDescriptor::FlagVector), 0u);
+  CHECK_SPLIT(DIDescriptor::FlagRValueReference, (DIDescriptor::FlagRValueReference), 0u);
+  CHECK_SPLIT(DIDescriptor::FlagFwdDecl | DIDescriptor::FlagVector,
+              (DIDescriptor::FlagFwdDecl, DIDescriptor::FlagVector), 0u);
+  CHECK_SPLIT(0x100000u, (), 0x100000u);
+  CHECK_SPLIT(0x100000u | DIDescriptor::FlagVector, (DIDescriptor::FlagVector),
+              0x100000u);
+#undef CHECK_SPLIT
+}
+
 } // end namespace