fix #10068 (typedef not replaced when namespace is involved) (#3009)

This commit is contained in:
IOBYTE 2021-01-05 10:53:56 -05:00 committed by GitHub
parent f0b5668436
commit 8897ad3408
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 14 deletions

View File

@ -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<AstNodePtr> &children, const Token *def);
Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, const std::vector<AstNodePtr> &children2, const Token *def);
Token *createTokensCall(TokenList *tokenList);
void createTokensFunctionDecl(TokenList *tokenList);
void createTokensForCXXRecord(TokenList *tokenList);

View File

@ -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;
}

View File

@ -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<AstNode> AstNodePtr;\n"
" class AstNode {\n"
" public:\n"
" AstNode() {}\n"
" private:\n"
" void createTokens();\n"
" void createScope(const std::vector<AstNodePtr> &children);\n"
" };\n"
"}\n"
"void clangimport::AstNode::createTokens() {\n"
" AstNodePtr range;\n"
" range->createTokens();\n"
"}\n"
"void clangimport::AstNode::createScope(const std::vector<AstNodePtr> & 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"