From 59cc4798559c21b71ce366f2bae9ab386264cc48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 2 May 2018 20:55:11 +0200 Subject: [PATCH] Save bitfield bit counts --- lib/symboldatabase.cpp | 5 +++++ lib/symboldatabase.h | 11 ++++++----- lib/token.cpp | 1 + lib/token.h | 13 +++++++++++++ lib/tokenize.cpp | 2 ++ test/testtokenize.cpp | 11 +++++++++++ 6 files changed, 38 insertions(+), 5 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index aefb2282f..7fd7c6ad3 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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 << '\"'; diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 992ce8465..d324a0b8d 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -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); diff --git a/lib/token.cpp b/lib/token.cpp index d2d71660c..da8838505 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -49,6 +49,7 @@ Token::Token(Token **tokens) : _progressValue(0), _tokType(eNone), _flags(0), + _bits(0), _astOperand1(nullptr), _astOperand2(nullptr), _astParent(nullptr), diff --git a/lib/token.h b/lib/token.h index 19946031b..d5b119ab5 100644 --- a/lib/token.h +++ b/lib/token.h @@ -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; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 8636d3464..22d3735ec 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -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% ::|<|,|{|;"))) { diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index c17fe5880..233de4f7a 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -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 m;"; // namespace std is not used