From f6523e384bfeddcce65166ae7a5e02af9c84e900 Mon Sep 17 00:00:00 2001 From: "Zachary D. Blair" Date: Tue, 1 Jul 2014 23:59:04 -0700 Subject: [PATCH] Fixed 4979 (Doesn't allow any ordering of int modifiers) --- lib/tokenize.cpp | 43 +++++++++++++++++++++++++++++++++ lib/tokenize.h | 8 +++++++ test/testtokenize.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 19865dd53..7631c32b0 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3698,6 +3698,8 @@ bool Tokenizer::simplifyTokenList2() simplifyEmptyNamespaces(); + simplifyStaticConst(); + while (simplifyMathFunctions()) {}; validate(); @@ -5713,6 +5715,47 @@ void Tokenizer::simplifyStdType() } } +void Tokenizer::simplifyStaticConst() +{ + // This function will simplify the token list so that the qualifiers "static" + // and "const" appear in the reverse order to what is in the array below. + const char* qualifiers[] = {"const", "static"}; + + // Move 'const' before all other qualifiers and types and then + // move 'static' before all other qualifiers and types. + for (size_t i = 0; i < sizeof(qualifiers)/sizeof(qualifiers[0]); i++) { + const char* qualifier = qualifiers[i]; + for (Token *tok = list.front(); tok; tok = tok->next()) { + + // Keep searching for an instance of "static" or "const" + if (!tok->next() || tok->next()->str() != qualifier) + continue; + + // Look backwards to find the beginning of the declaration + Token* leftTok = tok; + for (; leftTok; leftTok = leftTok->previous()) { + if (!Token::Match(leftTok, "%type%|static|const|extern") || + (isCPP() && Token::Match(leftTok, "private:|protected:|public:"))) + break; + } + + // The token preceding the declaration should indicate the start of a statement + if (!leftTok || + leftTok == tok || + !Token::Match(leftTok, ";|{|}|private:|protected:|public:")) { + continue; + } + + // Move the qualifier to the left-most position in the declaration + tok->deleteNext(); + if (leftTok->next()) + leftTok->next()->insertToken(qualifier, true); + else + leftTok->insertToken(qualifier); + } + } +} + void Tokenizer::simplifyIfAndWhileAssign() { for (Token *tok = list.front(); tok; tok = tok->next()) { diff --git a/lib/tokenize.h b/lib/tokenize.h index 91cf0d1e1..1bb4b6ccc 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -258,6 +258,14 @@ public: */ void simplifyCompoundAssignment(); + /** + * Simplify the location of "static" and "const" qualifiers in + * a variable declaration or definition. + * Example: "int static const a;" => "static const a;" + * Example: "long long const static b;" => "static const long long b;" + */ + void simplifyStaticConst(); + /** * Simplify assignments in "if" and "while" conditions * Example: "if(a=b);" => "a=b;if(a);" diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index dd03dd7cc..e1c566509 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -581,6 +581,7 @@ private: TEST_CASE(simplifyMathFunctions_fma); TEST_CASE(simplifyMathExpressions); //ticket #1620 + TEST_CASE(simplifyStaticConst); TEST_CASE(compileLimits); // #5592 crash: gcc: testsuit: gcc.c-torture/compile/limits-declparen.c @@ -10464,6 +10465,61 @@ private: ASSERT_EQUALS(code6, tokenizeAndStringify(code6)); } + void simplifyStaticConst() { + const char code1[] = "class foo { public: bool const static c ; }"; + const char expected1[] = "class foo { public: static const bool c ; }"; + ASSERT_EQUALS(expected1, tokenizeAndStringify(code1, true)); + + const char code2[] = + "int long long f()\n" + "{\n" + "static const long long signed int i1;\n" + "static const long long int signed i2;\n" + "static const signed long long int i3;\n" + "static const signed int long long i4;\n" + "static const int signed long long i5;\n" + "static const int long long signed i6;\n" + "long long static const signed int i7;\n" + "long long static const int signed i8;\n" + "signed static const long long int i9;\n" + "signed static const int long long i10;\n" + "int static const signed long long i11;\n" + "int static const long long signed i12;\n" + "long long signed int static const i13;\n" + "long long int signed static const i14;\n" + "signed long long int static const i15;\n" + "signed int long long static const i16;\n" + "int signed long long static const i17;\n" + "int long long signed static const i18;\n" + "return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12\n" + "+ i13 + i14 + i15 + i16 + i17 + i18;\n" + "}"; + const char expected2[] = + "long long f ( )\n" + "{\n" + "static const signed long long i1 ;\n" + "static const signed long long i2 ;\n" + "static const signed long long i3 ;\n" + "static const signed long long i4 ;\n" + "static const signed long long i5 ;\n" + "static const signed long long i6 ;\n" + "static const long long signed int i7 ;\n" + "static const long long signed int i8 ;\n" + "static const signed int long long i9 ;\n" + "static const signed int long long i10 ;\n" + "static const int signed long long i11 ;\n" + "static const int signed long long i12 ;\n" + "static const signed long long i13 ;\n" + "static const signed long long i14 ;\n" + "static const signed long long i15 ;\n" + "static const signed long long i16 ;\n" + "static const signed long long i17 ;\n" + "static const signed long long i18 ;\n" + "return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12\n" + "+ i13 + i14 + i15 + i16 + i17 + i18 ;\n" + "}"; + ASSERT_EQUALS(expected2, tokenizeAndStringify(code2, true)); + } static std::string testAst(const char code[],bool verbose=false) { // tokenize given code..