[llvm][ADT] Implement `BitVector::{pop_,}back`

LLVM Programmer’s Manual strongly discourages the use of `std::vector<bool>` and suggests `llvm::BitVector` as a possible replacement.

Currently, some users of `std::vector<bool>` cannot switch to `llvm::BitVector` because it doesn't implement the `pop_back()` and `back()` functions.

To enable easy transition of `std::vector<bool>` users, this patch implements `llvm::BitVector::pop_back()` and `llvm::BitVector::back()`.

Reviewed By: dexonsmith

Differential Revision: https://reviews.llvm.org/D117115
This commit is contained in:
Jan Svoboda 2022-01-12 16:09:58 +01:00
parent 2a9e33db4f
commit 622354a522
8 changed files with 60 additions and 6 deletions

View File

@ -9,6 +9,7 @@
#include "FunctionSizeCheck.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "llvm/ADT/BitVector.h"
using namespace clang::ast_matchers;
@ -118,7 +119,7 @@ public:
std::vector<SourceLocation> NestingThresholders;
};
FunctionInfo Info;
std::vector<bool> TrackedParent;
llvm::BitVector TrackedParent;
unsigned StructNesting = 0;
unsigned CurrentNestingLevel = 0;
};

View File

@ -27,6 +27,7 @@
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Syntax/Tokens.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
@ -663,7 +664,7 @@ void parseNamespaceEvents(llvm::StringRef Code, const LangOptions &LangOpts,
// Stack of enclosing namespaces, e.g. {"clang", "clangd"}
std::vector<std::string> Enclosing; // Contains e.g. "clang", "clangd"
// Stack counts open braces. true if the brace opened a namespace.
std::vector<bool> BraceStack;
llvm::BitVector BraceStack;
enum {
Default,

View File

@ -58,7 +58,7 @@ namespace {
class ScopedDeclarationState {
public:
ScopedDeclarationState(UnwrappedLine &Line, std::vector<bool> &Stack,
ScopedDeclarationState(UnwrappedLine &Line, llvm::BitVector &Stack,
bool MustBeDeclaration)
: Line(Line), Stack(Stack) {
Line.MustBeDeclaration = MustBeDeclaration;
@ -74,7 +74,7 @@ public:
private:
UnwrappedLine &Line;
std::vector<bool> &Stack;
llvm::BitVector &Stack;
};
static bool isLineComment(const FormatToken &FormatTok) {

View File

@ -18,6 +18,7 @@
#include "FormatToken.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Format/Format.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/Support/Regex.h"
#include <stack>
#include <vector>
@ -231,7 +232,7 @@ private:
// We store for each line whether it must be a declaration depending on
// whether we are in a compound statement or not.
std::vector<bool> DeclarationScopeStack;
llvm::BitVector DeclarationScopeStack;
const FormatStyle &Style;
const AdditionalKeywords &Keywords;

View File

@ -444,6 +444,12 @@ public:
return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
}
/// Return the last element in the vector.
bool back() const {
assert(!empty() && "Getting last element of empty vector.");
return (*this)[size() - 1];
}
bool test(unsigned Idx) const {
return (*this)[Idx];
}
@ -465,6 +471,12 @@ public:
set(OldSize);
}
/// Pop one bit from the end of the vector.
void pop_back() {
assert(!empty() && "Empty vector has no element to pop.");
resize(size() - 1);
}
/// Test if any common bits are set.
bool anyCommon(const BitVector &RHS) const {
unsigned ThisWords = Bits.size();

View File

@ -462,6 +462,12 @@ public:
return getPointer()->operator[](Idx);
}
/// Return the last element in the vector.
bool back() const {
assert(!empty() && "Getting last element of empty vector.");
return (*this)[size() - 1];
}
bool test(unsigned Idx) const {
return (*this)[Idx];
}
@ -471,6 +477,12 @@ public:
resize(size() + 1, Val);
}
/// Pop one bit from the end of the vector.
void pop_back() {
assert(!empty() && "Empty vector has no element to pop.");
resize(size() - 1);
}
/// Test if any common bits are set.
bool anyCommon(const SmallBitVector &RHS) const {
if (isSmall() && RHS.isSmall())

View File

@ -13,6 +13,7 @@
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
@ -379,7 +380,7 @@ private:
/// time of assembly
struct tm TM;
std::vector<bool> EndStatementAtEOFStack;
BitVector EndStatementAtEOFStack;
AsmCond TheCondState;
std::vector<AsmCond> TheCondStack;

View File

@ -1171,21 +1171,25 @@ TYPED_TEST(BitVectorTest, PushBack) {
EXPECT_EQ(-1, Vec.find_first());
EXPECT_EQ(10U, Vec.size());
EXPECT_EQ(0U, Vec.count());
EXPECT_EQ(false, Vec.back());
Vec.push_back(true);
EXPECT_EQ(10, Vec.find_first());
EXPECT_EQ(11U, Vec.size());
EXPECT_EQ(1U, Vec.count());
EXPECT_EQ(true, Vec.back());
Vec.push_back(false);
EXPECT_EQ(10, Vec.find_first());
EXPECT_EQ(12U, Vec.size());
EXPECT_EQ(1U, Vec.count());
EXPECT_EQ(false, Vec.back());
Vec.push_back(true);
EXPECT_EQ(10, Vec.find_first());
EXPECT_EQ(13U, Vec.size());
EXPECT_EQ(2U, Vec.count());
EXPECT_EQ(true, Vec.back());
// Add a lot of values to cause reallocation.
for (int i = 0; i != 100; ++i) {
@ -1197,6 +1201,28 @@ TYPED_TEST(BitVectorTest, PushBack) {
EXPECT_EQ(102U, Vec.count());
}
TYPED_TEST(BitVectorTest, PopBack) {
TypeParam Vec(10, true);
EXPECT_EQ(10U, Vec.size());
EXPECT_EQ(10U, Vec.count());
EXPECT_EQ(true, Vec.back());
Vec.pop_back();
EXPECT_EQ(9U, Vec.size());
EXPECT_EQ(9U, Vec.count());
EXPECT_EQ(true, Vec.back());
Vec.push_back(false);
EXPECT_EQ(10U, Vec.size());
EXPECT_EQ(9U, Vec.count());
EXPECT_EQ(false, Vec.back());
Vec.pop_back();
EXPECT_EQ(9U, Vec.size());
EXPECT_EQ(9U, Vec.count());
EXPECT_EQ(true, Vec.back());
}
TYPED_TEST(BitVectorTest, DenseSet) {
DenseSet<TypeParam> Set;
TypeParam A(10, true);