Skip to content

Commit 8893e61

Browse files
committed
simplify and use Bits
1 parent 83595c4 commit 8893e61

File tree

8 files changed

+171
-202
lines changed

8 files changed

+171
-202
lines changed

include/mrdox/Metadata/Bits.hpp

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,18 @@ namespace mrdox {
2323

2424
/** A container of packed bits to describe metadata.
2525
26-
The container may be templated on the enumeration,
27-
this ensures type safety.
26+
The container may be templated on the
27+
enumeration, to ensure type safety.
2828
*/
29-
template<class... Enums>
29+
template<class Enum>
3030
class Bits
3131
{
32-
#if 0
3332
static_assert(std::is_enum_v<Enum>);
3433
static_assert(std::is_same_v<
3534
std::underlying_type_t<Enum>, std::uint32_t>);
3635
#ifdef __cpp_lib_is_scoped_enum
3736
static_assert(std::is_scoped_enum<Enum>);
3837
#endif
39-
#endif
40-
template<class T>
41-
static constexpr void count()
42-
{
43-
//static_assert(false, "enum not found");
44-
}
45-
46-
template<class T, class E0, class... En>
47-
static constexpr int count()
48-
{
49-
if constexpr(std::is_same_v<T, E0>)
50-
return 0;
51-
else
52-
return 1 + count<T, En...>();
53-
}
5438

5539
public:
5640
using value_type = std::uint32_t;
@@ -59,87 +43,79 @@ class Bits
5943
*/
6044
constexpr Bits() noexcept = default;
6145

62-
/** Return the size of the integer array representing the bits.
46+
/** Return the integer value of the bit set.
6347
*/
64-
static constexpr std::size_t
65-
size()
48+
constexpr value_type
49+
value() const noexcept
6650
{
67-
return sizeof...(Enums);
51+
return bits_;
6852
}
6953

70-
/** Return the index of the specified enum E in the pack.
54+
/** Return true or false for a flag.
7155
*/
72-
template<class E>
73-
static constexpr int
74-
indexof()
56+
template<Enum ID>
57+
requires (std::has_single_bit(value_type(ID)))
58+
constexpr bool
59+
get() const noexcept
7560
{
76-
return count<E, Enums...>();
61+
return bits_ & value_type(ID);
7762
}
7863

79-
/** Return a pointer to the beginning of the array of values.
64+
/** Return the value for an id.
8065
*/
81-
constexpr value_type const* data() const
66+
template<Enum ID, class T = value_type>
67+
requires (std::popcount(value_type(ID)) > 1)
68+
constexpr T
69+
get() const noexcept
8270
{
83-
return bits_;
71+
return static_cast<T>((bits_ & value_type(ID)) >>
72+
std::countr_zero(value_type(ID)));
8473
}
8574

8675
/** Set a flag to true (or false).
8776
*/
88-
template<class Enum>
77+
template<Enum ID>
78+
requires (std::has_single_bit(value_type(ID)))
8979
constexpr void
90-
set(Enum id, bool value = true) noexcept
80+
set(bool value = true) noexcept
9181
{
92-
Assert(std::has_single_bit(value_type(id)));
93-
constexpr auto I = indexof<Enum>();
9482
if(value)
95-
bits_[I] |= value_type(id);
83+
bits_ |= value_type(ID);
9684
else
97-
bits_[I] &= ~value_type(id);
85+
bits_ &= ~value_type(ID);
9886
}
9987

10088
/** Set an integer value for the id.
10189
*/
102-
template<class Enum, class Integer>
90+
template<Enum ID, class Integer>
91+
requires (std::popcount(value_type(ID)) > 1)
10392
constexpr void
104-
set(Enum id, Integer value) noexcept
93+
set(Integer value) noexcept
10594
{
106-
Assert(std::popcount(value_type(id)) > 1);
107-
Assert(value > 0);
108-
Assert(value_type(value) < (
109-
value_type(id) >>
110-
std::countr_zero(value_type(id))));
111-
constexpr auto I = indexof<Enum>();
112-
bits_[I] = (bits_[I] & ~value_type(id)) | (
113-
value_type(value) << std::countr_zero(value_type(id)));
95+
Assert(ID > 0);
96+
Assert(value_type(value) < (value_type(ID) >>
97+
std::countr_zero(value_type(ID))));
98+
bits_ = (bits_ & ~value_type(ID)) | (
99+
value_type(value) << std::countr_zero(
100+
value_type(ID)));
114101
}
115102

116-
/** Return true or false for a flag.
103+
/** Load all the bits at once.
117104
*/
118-
template<class Enum>
119-
constexpr bool
120-
get(Enum id) const noexcept
105+
constexpr void
106+
load(value_type value)
121107
{
122-
Assert(std::has_single_bit(value_type(id)));
123-
constexpr auto I = indexof<Enum>();
124-
return bits_[I] & value_type(id);
108+
bits_ = value;
125109
}
126110

127-
/** Return the value for an id.
128-
*/
129-
template<class Enum>
130-
constexpr value_type
131-
get(Enum id) const noexcept
111+
constexpr void
112+
merge(Bits&& other) noexcept
132113
{
133-
Assert(std::popcount(value_type(id)) > 1);
134-
constexpr auto I = indexof<Enum>();
135-
return (bits_[I] & value_type(id)) >>
136-
std::countr_zero(value_type(id));
114+
bits_ |= other.bits_;
137115
}
138116

139-
void merge(Bits&& other) noexcept;
140-
141117
private:
142-
value_type bits_[size()]{};
118+
value_type bits_ = 0;
143119
};
144120

145121
} // mrdox

include/mrdox/Metadata/Function.hpp

Lines changed: 24 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -28,98 +28,33 @@
2828
namespace clang {
2929
namespace mrdox {
3030

31+
/** Bit constants used with function specifiers.
32+
*/
33+
enum FnFlags0 : std::uint32_t
34+
{
35+
// 13 bits
36+
constBit = 0x00000001,
37+
constevalBit = 0x00000002,
38+
constexprBit = 0x00000004,
39+
inlineBit = 0x00000008,
40+
noexceptBit = 0x00000010,
41+
noreturnBit = 0x00000020,
42+
overrideBit = 0x00000040,
43+
pureBit = 0x00000080,
44+
specialBit = 0x00000100, // dtor, move/copy construct or assign
45+
trailReturnBit = 0x00000200,
46+
variadicBit = 0x00000400, // has a C-style "..." variadic
47+
virtualBit = 0x00000800,
48+
volatileBit = 0x00001000,
49+
50+
refQualifierMask = 0x18000000, // 2 bits
51+
storageClassMask = 0xE0000000 // top 3 bits
52+
};
53+
3154
// TODO: Expand to allow for documenting templating and default args.
3255
// Info for functions.
3356
struct FunctionInfo : SymbolInfo
3457
{
35-
/** Bit constants used with function specifiers.
36-
*/
37-
enum Flags : std::uint32_t
38-
{
39-
// 13 bits
40-
constBit = 0x00000001,
41-
constevalBit = 0x00000002,
42-
constexprBit = 0x00000004,
43-
inlineBit = 0x00000008,
44-
noexceptBit = 0x00000010,
45-
noreturnBit = 0x00000020,
46-
overrideBit = 0x00000040,
47-
pureBit = 0x00000080,
48-
specialBit = 0x00000100, // dtor, move/copy construct or assign
49-
trailReturnBit = 0x00000200,
50-
variadicBit = 0x00000400, // has a C-style "..." variadic
51-
virtualBit = 0x00000800,
52-
volatileBit = 0x00001000,
53-
54-
refQualifierMask = 0x18000000, // 2 bits
55-
storageClassMask = 0xE0000000 // top 3 bits
56-
};
57-
58-
/** Specifiers for the function.
59-
60-
This is its own object to help the
61-
serializer out with converting to and
62-
from bitcode, and to help with merging.
63-
*/
64-
class Specs
65-
{
66-
public:
67-
using value_type = std::uint32_t;
68-
69-
Specs() = default;
70-
71-
explicit
72-
Specs(value_type bits) noexcept
73-
: bits_(bits)
74-
{
75-
}
76-
77-
value_type bits() const noexcept
78-
{
79-
return bits_;
80-
}
81-
82-
bool isSet(value_type bit) const noexcept
83-
{
84-
return bits_ & bit;
85-
}
86-
87-
RefQualifierKind refQualifier() const noexcept
88-
{
89-
return static_cast<RefQualifierKind>((
90-
bits_ & refQualifierMask) >> 11);
91-
}
92-
93-
StorageClass storageClass() const noexcept
94-
{
95-
return static_cast<StorageClass>((
96-
bits_ & storageClassMask) >> 13);
97-
}
98-
99-
void set(value_type bit, bool value = true) noexcept
100-
{
101-
if(value)
102-
bits_ |= bit;
103-
else
104-
bits_ &= ~bit;
105-
}
106-
107-
void setRefQualifier(RefQualifierKind k) noexcept
108-
{
109-
bits_ |= (static_cast<value_type>(k) << 11);
110-
}
111-
112-
void setStorageClass(StorageClass sc) noexcept
113-
{
114-
bits_ |= (static_cast<value_type>(sc) << 13);
115-
}
116-
117-
void merge(Specs&& other) noexcept;
118-
119-
private:
120-
value_type bits_ = 0;
121-
};
122-
12358
bool IsMethod = false; // Indicates whether this function is a class method.
12459
Reference Parent; // Reference to the parent class decl for this method.
12560
TypeInfo ReturnType; // Info about the return type of this function.
@@ -138,7 +73,7 @@ struct FunctionInfo : SymbolInfo
13873
// When present, this function is a template or specialization.
13974
llvm::Optional<TemplateInfo> Template;
14075

141-
Specs specs;
76+
Bits<FnFlags0> specs;
14277

14378
//--------------------------------------------
14479

source/lib/AST/BitcodeReader.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,24 @@ decodeRecord(
6767
return llvm::Error::success();
6868
}
6969

70+
// bits
71+
template<class... Enum>
72+
static
73+
llvm::Error
74+
decodeRecord(
75+
Record const& R,
76+
std::uint32_t* data,
77+
std::size_t n,
78+
llvm::StringRef blob)
79+
{
80+
auto n1 = *R.begin();
81+
if(n1 != n)
82+
return makeError("wrong size(", n1, ") for Bits(", n, ")");
83+
for(std::size_t i = 0; i < n1; ++i)
84+
data[i] = static_cast<std::uint32_t>(R.begin()[i + 1]);
85+
return llvm::Error::success();
86+
}
87+
7088
// container of char
7189
template<class Field>
7290
requires std::is_same_v<
@@ -87,7 +105,6 @@ decodeRecord(
87105
}
88106

89107
// range<SymbolID>
90-
91108
llvm::Error
92109
decodeRecord(
93110
Record const& R,
@@ -1093,10 +1110,10 @@ parseRecord(
10931110
return decodeRecord(R, I->IsMethod, Blob);
10941111
case FUNCTION_BITS:
10951112
{
1096-
FunctionInfo::Specs::value_type bits;
1097-
if(auto err = decodeRecord(R, bits, Blob))
1113+
std::uint32_t v;
1114+
if(auto err = decodeRecord(R, &v, 1, Blob))
10981115
return err;
1099-
I->specs = FunctionInfo::Specs(bits);
1116+
I->specs.load(v);
11001117
return llvm::Error::success();
11011118
}
11021119
default:

0 commit comments

Comments
 (0)