From 8629ae24e7fb14a9cadc5fc11dcbf262d665592f Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Sat, 21 Feb 2015 00:45:26 +0000 Subject: [PATCH] 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 --- include/llvm/IR/DebugInfo.h | 7 +++++++ lib/IR/DebugInfo.cpp | 24 ++++++++++++++++++++++++ unittests/IR/DebugInfoTest.cpp | 21 +++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index 1674b004f7b..8a103b1e9a3 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/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 &SplitFlags); + protected: const MDNode *DbgNode; diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index ad75fbae80d..6590661311a 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -55,6 +55,30 @@ const char *DIDescriptor::getFlagString(unsigned Flag) { } } +unsigned DIDescriptor::splitFlags(unsigned Flags, + SmallVectorImpl &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() || diff --git a/unittests/IR/DebugInfoTest.cpp b/unittests/IR/DebugInfoTest.cpp index fa05425e333..3c6c78651fa 100644 --- a/unittests/IR/DebugInfoTest.cpp +++ b/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 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