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;
}
}
+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() ||
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