diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9a44f6cd7..75fa0ebea 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3592,17 +3592,18 @@ void Tokenizer::simplifyExternC() // Add attributes to all tokens within `extern "C"` inlines and blocks, and remove the `extern "C"` tokens. for (Token *tok = list.front(); tok; tok = tok->next()) { - if (Token::simpleMatch(tok, "extern \"C\"")) { + if (Token::Match(tok, "extern \"C\"|\"C++\"")) { Token *tok2 = tok->next(); + const bool isExtC = tok->next()->str().size() == 3; if (tok->strAt(2) == "{") { tok2 = tok2->next(); // skip { while ((tok2 = tok2->next()) && tok2 != tok->linkAt(2)) - tok2->isExternC(true); + tok2->isExternC(isExtC); tok->linkAt(2)->deleteThis(); // } tok->deleteNext(2); // "C" { } else { while ((tok2 = tok2->next()) && !Token::Match(tok2, "[;{]")) - tok2->isExternC(true); + tok2->isExternC(isExtC); tok->deleteNext(); // "C" } tok->deleteThis(); // extern diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index aa4db7d84..03d62dbe7 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -4163,7 +4163,8 @@ private: void template163() { // #9685 syntax error const char code[] = "extern \"C++\" template < typename T > T * test ( ) { return nullptr ; }"; - ASSERT_EQUALS(code, tok(code)); + const char expected[] = "template < typename T > T * test ( ) { return nullptr ; }"; + ASSERT_EQUALS(expected, tok(code)); } void template164() { // #9394 diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 791e56c3b..245db59df 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -1548,8 +1548,47 @@ private: void simplifyExternC() { - ASSERT_EQUALS("int foo ( ) ;", tokenizeAndStringify("extern \"C\" int foo();")); - ASSERT_EQUALS("int foo ( ) ;", tokenizeAndStringify("extern \"C\" { int foo(); }")); + const char expected[] = "int foo ( ) ;"; + { + const char code[] = "extern \"C\" int foo();"; + // tokenize.. + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + // Expected result.. + ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); + ASSERT(tokenizer.tokens()->next()->isExternC()); + } + { + const char code[] = "extern \"C\" { int foo(); }"; + // tokenize.. + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + // Expected result.. + ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); + ASSERT(tokenizer.tokens()->next()->isExternC()); + } + { + const char code[] = "extern \"C++\" int foo();"; + // tokenize.. + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + // Expected result.. + ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); + ASSERT(!tokenizer.tokens()->next()->isExternC()); + } + { + const char code[] = "extern \"C++\" { int foo(); }"; + // tokenize.. + Tokenizer tokenizer(&settings0, this); + std::istringstream istr(code); + ASSERT(tokenizer.tokenize(istr, "test.cpp")); + // Expected result.. + ASSERT_EQUALS(expected, tokenizer.tokens()->stringifyList(nullptr, false)); + ASSERT(!tokenizer.tokens()->next()->isExternC()); + } } void simplifyFunctionParameters() {