From 84ce6ba75a89d3e71c90267360c934871bc473b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 29 Dec 2009 07:28:00 +0100 Subject: [PATCH] Robert Reif: Fixed #1162 (add support to tokenize typedefs with templates) --- lib/tokenize.cpp | 81 ++++++++++++++++++++++++++++++------- test/testsimplifytokens.cpp | 16 +++++++- 2 files changed, 80 insertions(+), 17 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index daebc015c..7fd74adea 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -395,11 +395,6 @@ void Tokenizer::simplifyTypedef() else if (tok->str() != "typedef") continue; - const char *type1 = 0; - const char *type2 = 0; - const char *typeName = 0; - bool pointer = false; - // pull struct name { ... } out of typedef if (Token::Match(tok->next(), "struct %type% {")) { @@ -472,10 +467,51 @@ void Tokenizer::simplifyTypedef() tok = tok3; } - if (Token::Match(tok->next(), "%type% *| %type% ;") || + const char *type1 = 0; + const char *type2 = 0; + const char *typeName = 0; + bool pointer = false; + Token *start = 0; + Token *end = 0; + + if (Token::Match(tok->next(), "%type% <") || + Token::Match(tok->next(), "%type% :: %type% <") || + Token::Match(tok->next(), "%type% *| %type% ;") || Token::Match(tok->next(), "%type% %type% *| %type% ;")) { - if (tok->tokAt(3)->str() == ";") + if ((tok->tokAt(2)->str() == "<") || + (tok->tokAt(4) && (tok->tokAt(4)->str() == "<"))) + { + int level = 1; + start = tok->next(); + + if (tok->tokAt(2)->str() == "<") + end = tok->tokAt(3); + else + end = tok->tokAt(5); + + for (; end ; end = end->next()) + { + if (end->str() == ">") + { + level--; + if (level == 0) + break; + } + + if (end->str() == "<") + level++; + } + + if (Token::Match(end->next(), "%type% ;")) + { + typeName = end->strAt(1); + tok = end->tokAt(2); + } + else + continue; + } + else if (tok->tokAt(3)->str() == ";") { type1 = tok->strAt(1); type2 = 0; @@ -548,7 +584,9 @@ void Tokenizer::simplifyTypedef() Token::Match(tok2->tokAt(-3), "!!typedef")) { // Check for enum and typedef with same name. - if (tok2->tokAt(-1)->str() != type1) + if (type1 && (tok2->tokAt(-1)->str() != type1)) + simplifyType = true; + else if (!type1) simplifyType = true; } else @@ -561,16 +599,29 @@ void Tokenizer::simplifyTypedef() if (simplifyType) { - tok2->str(type1); - if (type2) + if (start && end) { - tok2->insertToken(type2); - tok2 = tok2->next(); + tok2->str(start->str()); + Token * nextToken; + for (nextToken = start->next(); nextToken != end->next(); nextToken = nextToken->next()) + { + tok2->insertToken(nextToken->strAt(0)); + tok2 = tok2->next(); + } } - if (pointer) + else { - tok2->insertToken("*"); - tok2 = tok2->next(); + tok2->str(type1); + if (type2) + { + tok2->insertToken(type2); + tok2 = tok2->next(); + } + if (pointer) + { + tok2->insertToken("*"); + tok2 = tok2->next(); + } } simplifyType = false; diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index 148bb892f..f021ef214 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -2294,6 +2294,9 @@ private: "typedef struct t { int a; } T, *TP;" "typedef enum { a = 0 , b = 1 , c = 2 } abc;" "typedef enum xyz { a = 0 , b = 1 , c = 2 } ABC;" + "typedef vector V1;" + "typedef std::vector V2;" + "typedef std::vector > V3;" "INT ti;\n" "UINT tui;\n" "PINT tpi;\n" @@ -2303,7 +2306,10 @@ private: "T t;\n" "TP tp;\n" "abc e1;\n" - "ABC e2;"; + "ABC e2;\n" + "V1 v1;\n" + "V2 v2;\n" + "V3 v3;"; const char expected[] = "typedef int INT ; " @@ -2314,6 +2320,9 @@ private: "struct t { int a ; } ; typedef struct t T ; typedef struct t * TP ; " "enum abc { a = 0 , b = 1 , c = 2 } ; typedef enum abc abc ; " "enum xyz { a = 0 , b = 1 , c = 2 } ; typedef enum xyz ABC ; " + "typedef vector < int > V1 ; " + "typedef std :: vector < int > V2 ; " + "typedef std :: vector < std :: vector < int > > V3 ; " "int ti ; " "unsigned int tui ; " "int * tpi ; " @@ -2323,7 +2332,10 @@ private: "struct t t ; " "struct t * tp ; " "enum abc e1 ; " - "enum xyz e2 ;"; + "enum xyz e2 ; " + "vector < int > v1 ; " + "std :: vector < int > v2 ; " + "std :: vector < std :: vector < int > > v3 ;"; ASSERT_EQUALS(expected, tok(code, false)); }