IR: Add helper to split debug info flags bitfield
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sat, 21 Feb 2015 00:45:26 +0000 (00:45 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sat, 21 Feb 2015 00:45:26 +0000 (00:45 +0000)
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

include/llvm/IR/DebugInfo.h
lib/IR/DebugInfo.cpp
unittests/IR/DebugInfoTest.cpp

index 1674b004f7bb927c7b0620254fd407fb178c0711..8a103b1e9a31236af072f4bcac6c72b95e378a0b 100644 (file)
@@ -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;
 
index ad75fbae80db6ecf87f45cd7af80708e56f3ce76..6590661311ac6efe24278e9f7aec7326283b5cfe 100644 (file)
@@ -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() ||
index fa05425e333daaf199b19f271f600a3833fea4a4..3c6c78651fa5f2d7f4b0fcb914a73f30a9bbff6c 100644 (file)
@@ -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