diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 07957fce1..f1238eafe 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -337,7 +337,7 @@ namespace clangimport { const ::Type *addTypeTokens(TokenList *tokenList, const std::string &str, const Scope *scope = nullptr); void addFullScopeNameTokens(TokenList *tokenList, const Scope *recordScope); Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, AstNodePtr astNode, const Token *def); - Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, const std::vector &children, const Token *def); + Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, const std::vector &children2, const Token *def); Token *createTokensCall(TokenList *tokenList); void createTokensFunctionDecl(TokenList *tokenList); void createTokensForCXXRecord(TokenList *tokenList); diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 009ae584d..2245090c3 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -1069,17 +1069,8 @@ void Tokenizer::simplifyTypedef() } // check for member functions - else if (isCPP() && Token::Match(tok2, ")|] const| {")) { - const Token *temp = tok2; - while (temp && temp->str() == "]" && temp->link() && temp->link()->previous()) - temp = temp->link()->previous(); - if (!temp || !temp->link() || !temp->link()->previous()) - continue; - const Token *func = temp->link()->previous(); - if (temp->str() != ")") - continue; - if (!func->previous()) // Ticket #4239 - continue; + else if (isCPP() && tok2->str() == "(" && isFunctionHead(tok2, "{")) { + const Token *func = tok2->previous(); /** @todo add support for multi-token operators */ if (func->previous()->str() == "operator") @@ -1089,10 +1080,13 @@ void Tokenizer::simplifyTypedef() syntaxError(func); // check for qualifier - if (func->previous()->str() == "::") { + if (Token::Match(func->tokAt(-2), "%name% ::")) { + int offset = -2; + while (Token::Match(func->tokAt(offset - 2), "%name% ::")) + offset -= 2; // check for available and matching class name if (!spaceInfo.empty() && classLevel < spaceInfo.size() && - func->strAt(-2) == spaceInfo[classLevel].className) { + func->strAt(offset) == spaceInfo[classLevel].className) { memberScope = 0; inMemberFunc = true; } diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index 405ced7e3..e9b8a223c 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -175,6 +175,7 @@ private: TEST_CASE(simplifyTypedef132); // ticket #9739 - using TEST_CASE(simplifyTypedef133); // ticket #9812 - using TEST_CASE(simplifyTypedef134); + TEST_CASE(simplifyTypedef135); // ticket #10068 TEST_CASE(simplifyTypedefFunction1); TEST_CASE(simplifyTypedefFunction2); // ticket #1685 @@ -2675,6 +2676,42 @@ private: ASSERT_EQUALS("namespace foo { long long i ; } int j ;", tok(code, false)); } + void simplifyTypedef135() { + const char code[] = "namespace clangimport {\n" + " class AstNode;\n" + " typedef std::shared_ptr AstNodePtr;\n" + " class AstNode {\n" + " public:\n" + " AstNode() {}\n" + " private:\n" + " void createTokens();\n" + " void createScope(const std::vector &children);\n" + " };\n" + "}\n" + "void clangimport::AstNode::createTokens() {\n" + " AstNodePtr range;\n" + " range->createTokens();\n" + "}\n" + "void clangimport::AstNode::createScope(const std::vector & children2) { }"; + const char expected[] = "namespace clangimport { " + "class AstNode ; " + "class AstNode { " + "public: " + "AstNode ( ) " + "{ } " + "private: " + "void createTokens ( ) ; " + "void createScope ( const std :: vector < std :: shared_ptr < AstNode > > & children ) ; " + "} ; " + "} " + "void clangimport :: AstNode :: createTokens ( ) { " + "std :: shared_ptr < AstNode > range ; " + "range . createTokens ( ) ; " + "} " + "void clangimport :: AstNode :: createScope ( const std :: vector < std :: shared_ptr < AstNode > > & children2 ) { }"; + ASSERT_EQUALS(expected, tok(code)); + } + void simplifyTypedefFunction1() { { const char code[] = "typedef void (*my_func)();\n"