Save bitfield bit counts

This commit is contained in:
Daniel Marjamäki 2018-05-02 20:55:11 +02:00
parent 8d3570debf
commit 59cc479855
6 changed files with 38 additions and 5 deletions

View File

@ -4746,6 +4746,8 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V
void SymbolDatabase::setValueType(Token *tok, const Variable &var)
{
ValueType valuetype;
if (var.nameToken())
valuetype.bits = var.nameToken()->bits();
valuetype.pointer = var.dimensions().size();
valuetype.typeScope = var.typeScope();
if (parsedecl(var.typeStartToken(), &valuetype, defaultSignedness, _settings))
@ -5520,6 +5522,9 @@ std::string ValueType::dump() const
break;
};
if (bits > 0)
ret << " valueType-bits=\"" << bits << '\"';
if (pointer > 0)
ret << " valueType-pointer=\"" << pointer << '\"';

View File

@ -1062,6 +1062,7 @@ private:
public:
enum Sign { UNKNOWN_SIGN, SIGNED, UNSIGNED } sign;
enum Type { UNKNOWN_TYPE, NONSTD, RECORD, CONTAINER, ITERATOR, VOID, BOOL, CHAR, SHORT, INT, LONG, LONGLONG, UNKNOWN_INT, FLOAT, DOUBLE, LONGDOUBLE } type;
unsigned int bits; ///< bitfield bitcount
unsigned int pointer; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
unsigned int constness; ///< bit 0=data, bit 1=*, bit 2=**
const Scope *typeScope; ///< if the type definition is seen this point out the type scope
@ -1069,11 +1070,11 @@ public:
const Token *containerTypeToken; ///< The container type token. the template argument token that defines the container element type.
std::string originalTypeName; ///< original type name as written in the source code. eg. this might be "uint8_t" when type is CHAR.
ValueType() : sign(UNKNOWN_SIGN), type(UNKNOWN_TYPE), pointer(0U), constness(0U), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {}
ValueType(const ValueType &vt) : sign(vt.sign), type(vt.type), pointer(vt.pointer), constness(vt.constness), typeScope(vt.typeScope), container(vt.container), containerTypeToken(vt.containerTypeToken), originalTypeName(vt.originalTypeName) {}
ValueType(enum Sign s, enum Type t, unsigned int p) : sign(s), type(t), pointer(p), constness(0U), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {}
ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {}
ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c, const std::string &otn) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr), originalTypeName(otn) {}
ValueType() : sign(UNKNOWN_SIGN), type(UNKNOWN_TYPE), bits(0), pointer(0U), constness(0U), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {}
ValueType(const ValueType &vt) : sign(vt.sign), type(vt.type), bits(vt.bits), pointer(vt.pointer), constness(vt.constness), typeScope(vt.typeScope), container(vt.container), containerTypeToken(vt.containerTypeToken), originalTypeName(vt.originalTypeName) {}
ValueType(enum Sign s, enum Type t, unsigned int p) : sign(s), type(t), bits(0), pointer(p), constness(0U), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {}
ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c) : sign(s), type(t), bits(0), pointer(p), constness(c), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {}
ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c, const std::string &otn) : sign(s), type(t), bits(0), pointer(p), constness(c), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr), originalTypeName(otn) {}
static ValueType parseDecl(const Token *type, const Settings *settings);

View File

@ -49,6 +49,7 @@ Token::Token(Token **tokens) :
_progressValue(0),
_tokType(eNone),
_flags(0),
_bits(0),
_astOperand1(nullptr),
_astOperand2(nullptr),
_astParent(nullptr),

View File

@ -423,6 +423,16 @@ public:
setFlag(fIsEnumType, value);
}
bool isBitfield() const {
return _bits > 0;
}
unsigned char bits() const {
return _bits;
}
void setBits(unsigned char b) {
_bits = b;
}
/**
* @brief Is current token a template argument?
*
@ -956,6 +966,9 @@ private:
/** Update internal property cache about isStandardType() */
void update_property_isStandardType();
/** Bitfield bit count. */
unsigned char _bits;
// AST..
Token *_astOperand1;
Token *_astOperand2;

View File

@ -9283,6 +9283,8 @@ void Tokenizer::simplifyBitfields()
!Token::Match(tok->next(), "case|public|protected|private|class|struct") &&
!Token::simpleMatch(tok->tokAt(2), "default :")) {
Token *tok1 = (tok->next()->str() == "const") ? tok->tokAt(3) : tok->tokAt(2);
if (Token::Match(tok1, "%name% : %num% ;"))
tok1->setBits(MathLib::toLongNumber(tok1->strAt(2)));
if (tok1 && tok1->tokAt(2) &&
(Token::Match(tok1->tokAt(2), "%bool%|%num%") ||
!Token::Match(tok1->tokAt(2), "public|protected|private| %type% ::|<|,|{|;"))) {

View File

@ -361,6 +361,7 @@ private:
TEST_CASE(bitfields13); // ticket #3502 (segmentation fault)
TEST_CASE(bitfields14); // ticket #4561 (segfault for 'class a { signals: };')
TEST_CASE(bitfields15); // ticket #7747 (enum Foo {A,B}:4;)
TEST_CASE(bitfields16); // Save bitfield bit count
TEST_CASE(simplifyNamespaceStd);
@ -5565,6 +5566,16 @@ private:
"};"));
}
void bitfields16() {
const char code[] = "struct A { unsigned int x : 1; };";
errout.str("");
Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
const Token *x = Token::findsimplematch(tokenizer.tokens(), "x");
ASSERT_EQUALS(1, x->bits());
}
void simplifyNamespaceStd() {
static const char code1[] = "map<foo, bar> m;"; // namespace std is not used