diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 6bdee6618dc..7b4c21193f9 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -828,6 +828,8 @@ namespace { Token* const tok2 = insertTokens(tok, rangeType); Token* const tok3 = insertTokens(tok2, mRangeTypeQualifiers); + tok2->originalName(tok->str()); + tok3->originalName(tok->str()); Token *after = tok3; while (Token::Match(after, "%name%|*|&|&&|::")) after = after->next(); diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp index b3096edffcb..a63538f346b 100644 --- a/test/testsimplifytypedef.cpp +++ b/test/testsimplifytypedef.cpp @@ -230,6 +230,8 @@ class TestSimplifyTypedef : public TestFixture { TEST_CASE(simplifyTypedefShadow); // #4445 - shadow variable TEST_CASE(simplifyTypedefMacro); + + TEST_CASE(simplifyTypedefOriginalName); } #define tok(...) tok_(__FILE__, __LINE__, __VA_ARGS__) @@ -4131,6 +4133,62 @@ class TestSimplifyTypedef : public TestFixture { ASSERT_EQUALS("void foo ( uint32_t prev_segment ) { if ( prev_segment == ( ( uint32_t ) 12 ) ) { } }", simplifyTypedefP(code)); } + + void simplifyTypedefOriginalName() { + const char code[] = "typedef unsigned char uint8_t;" + "typedef float (*rFunctionPointer_fp)(uint8_t, uint8_t);" + "typedef enum eEnumDef {" + " ABC = 0," + "}eEnum_t;" + "typedef enum {" + " ABC = 0," + "}eEnum2_t;" + "typedef short int16_t;" + "typedef struct stStructDef {" + " int16_t swA;" + "}stStruct_t;" + "double endOfTypeDef;" + "eEnum2_t enum2Type;" + "stStruct_t structType;" + "eEnum_t enumType;" + "uint8_t t;" + "void test(rFunctionPointer_fp functionPointer);"; + + Tokenizer tokenizer(settings1, this); + std::istringstream istr(code); + tokenizer.list.createTokens(istr, "file.c"); + tokenizer.createLinks(); + tokenizer.simplifyTypedef(); + + try { + tokenizer.validate(); + } + catch (const InternalError&) { + ASSERT_EQUALS_MSG(false, true, "Validation of Tokenizer failed"); + } + + const Token* token; + // Get the Token which is at the end of all the Typedef's in this case i placed a variable + const Token* endOfTypeDef = Token::findsimplematch(tokenizer.list.front(), "endOfTypeDef", tokenizer.list.back()); + // Search for the simplified char token and check its original Name + token = Token::findsimplematch(endOfTypeDef, "char", tokenizer.list.back()); + ASSERT_EQUALS("uint8_t", token->originalName()); + // Search for the simplified eEnumDef token and check its original Name + token = Token::findsimplematch(endOfTypeDef, "eEnumDef", tokenizer.list.back()); + ASSERT_EQUALS("eEnum_t", token->originalName()); + // Search for the eEnum2_t token as it does not have a name it should be the direct type name + token = Token::findsimplematch(endOfTypeDef, "eEnum2_t", tokenizer.list.back()); + ASSERT_EQUALS("eEnum2_t", token->str()); + // Search for the simplified stStructDef token and check its original Name + token = Token::findsimplematch(endOfTypeDef, "stStructDef", tokenizer.list.back()); + ASSERT_EQUALS("stStruct_t", token->originalName()); + // Search for the simplified short token and check its original Name, start from front to get the variable in the struct + token = Token::findsimplematch(tokenizer.list.front(), "short", tokenizer.list.back()); + ASSERT_EQUALS("int16_t", token->originalName()); + // Search for the simplified * token -> function pointer gets "(*" tokens infront of it + token = Token::findsimplematch(endOfTypeDef, "*", tokenizer.list.back()); + ASSERT_EQUALS("rFunctionPointer_fp", token->originalName()); + } }; REGISTER_TEST(TestSimplifyTypedef) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 670ca8f6a22..4322356367d 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -1411,6 +1411,53 @@ class TestSymbolDatabase : public TestFixture { ASSERT(p->valueType()->volatileness == 2); ASSERT(p->valueType()->reference == Reference::None); } + { + GET_SYMBOL_DB_C("typedef unsigned char uint8_t;\n uint8_t ubVar = 0;\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p->valueType()); + ASSERT(p->valueType()->pointer == 0); + ASSERT(p->valueType()->constness == 0); + ASSERT(p->valueType()->volatileness == 0); + ASSERT(p->valueType()->originalTypeName == "uint8_t"); + ASSERT(p->valueType()->reference == Reference::None); + } + { + GET_SYMBOL_DB_C("typedef enum eEnumDef {CPPCHECK=0}eEnum_t;\n eEnum_t eVar = CPPCHECK;\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p->valueType()); + ASSERT(p->valueType()->pointer == 0); + ASSERT(p->valueType()->constness == 0); + ASSERT(p->valueType()->volatileness == 0); + ASSERT(p->valueType()->originalTypeName == "eEnum_t"); + ASSERT(p->valueType()->reference == Reference::None); + } + { + GET_SYMBOL_DB_C("typedef unsigned char uint8_t;\n typedef struct stStructDef {uint8_t ubTest;}stStruct_t;\n stStruct_t stVar;\n"); + const Variable* p = db->getVariableFromVarId(1); + ASSERT(p->valueType()); + ASSERT(p->valueType()->pointer == 0); + ASSERT(p->valueType()->constness == 0); + ASSERT(p->valueType()->volatileness == 0); + ASSERT(p->valueType()->originalTypeName == "uint8_t"); + ASSERT(p->valueType()->reference == Reference::None); + p = db->getVariableFromVarId(2); + ASSERT(p->valueType()); + ASSERT(p->valueType()->pointer == 0); + ASSERT(p->valueType()->constness == 0); + ASSERT(p->valueType()->volatileness == 0); + ASSERT(p->valueType()->originalTypeName == "stStruct_t"); + ASSERT(p->valueType()->reference == Reference::None); + } + { + GET_SYMBOL_DB_C("typedef int (*ubFunctionPointer_fp)(int);\n void test(ubFunctionPointer_fp functionPointer);\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p->valueType()); + ASSERT(p->valueType()->pointer == 1); + ASSERT(p->valueType()->constness == 0); + ASSERT(p->valueType()->volatileness == 0); + ASSERT(p->valueType()->originalTypeName == "ubFunctionPointer_fp"); + ASSERT(p->valueType()->reference == Reference::None); + } } void VariableValueTypeTemplate() {