diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6e71c14cb..5b25a2aeb 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -732,14 +732,17 @@ void Tokenizer::simplifyTypedef() Token *typeDef = tok; Token *argFuncRetStart = 0; Token *argFuncRetEnd = 0; - Token *const1= 0; - Token *const2= 0; + Token *const1 = 0; + Token *const2 = 0; int offset = 1; bool function = false; bool functionPtr = false; bool functionRef = false; bool functionRetFuncPtr = false; bool functionPtrRetFuncPtr = false; + bool ptrToArray = false; + bool refToArray = false; + bool ptrMember = false; Token *functionNamespace = 0; if (Token::Match(tok->next(), "::") || @@ -1027,6 +1030,26 @@ void Tokenizer::simplifyTypedef() tok = argFuncRetEnd->next(); } + // pointer/reference to array + else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( *|& %type% ) [")) + { + ptrToArray = (tok->tokAt(offset + 1)->str() == "*"); + refToArray = (tok->tokAt(offset + 1)->str() == "&"); + typeName = tok->tokAt(offset + 2); + arrayStart = tok->tokAt(offset + 4); + arrayEnd = arrayStart->link(); + tok = arrayEnd->next(); + } + + // pointer to class member + else if (tok->tokAt(offset) && Token::Match(tok->tokAt(offset), "( %type% :: * %type% ) ;")) + { + functionNamespace = tok->tokAt(offset + 1); + ptrMember = true; + typeName = tok->tokAt(offset + 4); + tok = tok->tokAt(offset + 6); + } + // unhandled typedef, skip it and continue else { @@ -1381,6 +1404,46 @@ void Tokenizer::simplifyTypedef() tok2 = tok2->next(); Token::createMutualLinks(tok2, tok6); } + else if (ptrToArray || refToArray) + { + tok2->insertToken("("); + tok2 = tok2->next(); + Token *tok3 = tok2; + + if (ptrToArray) + tok2->insertToken("*"); + else + tok2->insertToken("&"); + tok2 = tok2->next(); + + // skip over name + tok2 = tok2->next(); + + tok2->insertToken(")"); + Token::createMutualLinks(tok2->next(), tok3); + } + else if (ptrMember) + { + tok2->insertToken("("); + tok2 = tok2->next(); + Token *tok3 = tok2; + + tok2->insertToken(functionNamespace->str()); + tok2 = tok2->next(); + + tok2->insertToken("::"); + tok2 = tok2->next(); + + tok2->insertToken("*"); + tok2 = tok2->next(); + + // skip over name + tok2 = tok2->next(); + + tok2->insertToken(")"); + tok2 = tok2->next(); + Token::createMutualLinks(tok2, tok3); + } if (arrayStart && arrayEnd) { diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 6e695371c..4f7389400 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -192,6 +192,8 @@ private: TEST_CASE(simplifyTypedef47); TEST_CASE(simplifyTypedef48); // ticket #1673 TEST_CASE(simplifyTypedef49); // ticket #1691 + TEST_CASE(simplifyTypedef50); + TEST_CASE(simplifyTypedef51); TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -4010,6 +4012,38 @@ private: ASSERT_EQUALS(expected, sizeof_(code)); } + void simplifyTypedef50() + { + const char code[] = "typedef char (* type1)[10];\n" + "typedef char (& type2)[10];\n" + "typedef char (& type3)[x];\n" + "typedef char (& type4)[x + 2];\n" + "type1 t1;\n" + "type2 t2;\n" + "type3 t3;\n" + "type4 t4;"; + + // The expected result.. + const std::string expected("; ; ; ; " + "char ( * t1 ) [ 10 ] ; " + "char ( & t2 ) [ 10 ] ; " + "char ( & t3 ) [ x ] ; " + "char ( & t4 ) [ x + 2 ] ;"); + ASSERT_EQUALS(expected, sizeof_(code)); + } + + void simplifyTypedef51() + { + const char code[] = "class A { public: int i; };\n" + "typedef const char (A :: * type1);\n" + "type1 t1 = &A::i;"; + + // The expected result.. + const std::string expected("class A { public: int i ; } ; ; " + "const char ( A :: * t1 ) = & A :: i ;"); + ASSERT_EQUALS(expected, sizeof_(code)); + } + void simplifyTypedefFunction1() { {