Skip to content

Commit 0d8e8cc

Browse files
author
Your Name
committed
Fix CI issues
1 parent 1aa06fc commit 0d8e8cc

5 files changed

Lines changed: 45 additions & 26 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,17 +1875,29 @@ void SymbolDatabase::removeSymbolsForTokens(const std::unordered_set<const Token
18751875

18761876
// the scopes, functions, variables, types and enumerators declared by those tokens
18771877
std::unordered_set<const Scope*> removedScopes;
1878+
std::unordered_set<const Variable*> removedVariables;
1879+
std::unordered_set<const Enumerator*> removedEnumerators;
18781880
for (const Scope& scope : scopeList) {
18791881
if ((scope.classDef && removedTokens.count(scope.classDef) != 0) ||
1880-
(scope.bodyStart && removedTokens.count(scope.bodyStart) != 0))
1882+
(scope.bodyStart && removedTokens.count(scope.bodyStart) != 0)) {
18811883
removedScopes.insert(&scope);
1884+
std::transform(scope.varlist.cbegin(), scope.varlist.cend(), std::inserter(removedVariables, removedVariables.end()), [](const Variable& var) {
1885+
return &var;
1886+
});
1887+
std::transform(scope.enumeratorList.cbegin(), scope.enumeratorList.cend(), std::inserter(removedEnumerators, removedEnumerators.end()), [](const Enumerator& enumerator) {
1888+
return &enumerator;
1889+
});
1890+
}
18821891
}
18831892
std::unordered_set<const Function*> removedFunctions;
18841893
for (Scope& scope : scopeList) {
18851894
for (Function& function : scope.functionList) {
1886-
if (function.tokenDef && removedTokens.count(function.tokenDef) != 0)
1895+
if (function.tokenDef && removedTokens.count(function.tokenDef) != 0) {
18871896
removedFunctions.insert(&function);
1888-
else if (function.token && removedTokens.count(function.token) != 0) {
1897+
std::transform(function.argumentList.cbegin(), function.argumentList.cend(), std::inserter(removedVariables, removedVariables.end()), [](const Variable& arg) {
1898+
return &arg;
1899+
});
1900+
} else if (function.token && removedTokens.count(function.token) != 0) {
18891901
// only the function definition is removed - the declaration remains
18901902
function.token = nullptr;
18911903
function.arg = function.argDef;
@@ -1894,28 +1906,11 @@ void SymbolDatabase::removeSymbolsForTokens(const std::unordered_set<const Token
18941906
}
18951907
}
18961908
}
1897-
std::unordered_set<const Variable*> removedVariables;
1898-
for (const Scope* scope : removedScopes) {
1899-
std::transform(scope->varlist.cbegin(), scope->varlist.cend(), std::inserter(removedVariables, removedVariables.end()), [](const Variable& var) {
1900-
return &var;
1901-
});
1902-
}
1903-
for (const Function* function : removedFunctions) {
1904-
std::transform(function->argumentList.cbegin(), function->argumentList.cend(), std::inserter(removedVariables, removedVariables.end()), [](const Variable& arg) {
1905-
return &arg;
1906-
});
1907-
}
19081909
std::unordered_set<const Type*> removedTypes;
19091910
for (const Type& type : typeList) {
19101911
if (type.classDef && removedTokens.count(type.classDef) != 0)
19111912
removedTypes.insert(&type);
19121913
}
1913-
std::unordered_set<const Enumerator*> removedEnumerators;
1914-
for (const Scope* scope : removedScopes) {
1915-
std::transform(scope->enumeratorList.cbegin(), scope->enumeratorList.cend(), std::inserter(removedEnumerators, removedEnumerators.end()), [](const Enumerator& enumerator) {
1916-
return &enumerator;
1917-
});
1918-
}
19191914

19201915
// clear the references from the surviving tokens
19211916
for (Token* tok = mTokenizer.list.front(); tok; tok = tok->next()) {
@@ -2004,7 +1999,11 @@ void SymbolDatabase::addSymbolsForNewTokenRanges(const std::vector<std::pair<Tok
20041999
const Scope* enclosing = anchor ? anchor->scope() : &scopeList.front();
20052000
if (!enclosing)
20062001
continue;
2007-
if (anchor && anchor == enclosing->bodyEnd)
2002+
// an anchor that closes the enclosing scope means the new tokens are in its parent.
2003+
// a namespace can consist of multiple blocks and bodyStart/bodyEnd only track the
2004+
// latest block - so for namespaces any closing brace with the namespace scope closes it.
2005+
if (anchor && anchor->str() == "}" &&
2006+
(anchor == enclosing->bodyEnd || enclosing->type == ScopeType::eNamespace))
20082007
enclosing = enclosing->nestedIn ? enclosing->nestedIn : &scopeList.front();
20092008
findAllScopes(range.first, range.second->next(), const_cast<Scope*>(enclosing));
20102009
}

lib/token.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ void Token::function(const Function *f)
10571057
else
10581058
tokType(eFunction);
10591059
} else if (mTokType == eFunction)
1060-
tokType(eName);
1060+
update_property_info(); // eType for standard types, eKeyword for keywords, eName otherwise
10611061
}
10621062

10631063
Token* Token::insertToken(const std::string& tokenStr, bool prepend)
@@ -2337,7 +2337,7 @@ void Token::type(const ::Type *t)
23372337
tokType(eType);
23382338
isEnumType(mImpl->mType->isEnumType());
23392339
} else if (mTokType == eType)
2340-
tokType(eName);
2340+
update_property_info(); // eType for standard types, eKeyword for keywords, eName otherwise
23412341
}
23422342

23432343
const ::Type* Token::typeOf(const Token* tok, const Token** typeTok)

lib/token.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,7 @@ class CPPCHECKLIB Token {
12421242
if (v || mImpl->mVarId)
12431243
tokType(eVariable);
12441244
else if (mTokType == eVariable)
1245-
tokType(eName);
1245+
update_property_info(); // eType for standard types, eKeyword for keywords, eName otherwise
12461246
}
12471247

12481248
/**

lib/tokenize.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4404,7 +4404,7 @@ void Tokenizer::updateTokenDataAfterTemplateSimplification()
44044404
if (tok == region.second)
44054405
break;
44064406
}
4407-
list.createAst(region.first, region.second->next());
4407+
TokenList::createAst(region.first, region.second->next());
44084408
}
44094409
}
44104410
list.validateAst(mSettings.debugnormal);
@@ -4421,7 +4421,10 @@ void Tokenizer::updateTokenDataAfterTemplateSimplification()
44214421
for (Token* tok = list.front(); tok; tok = tok->next()) {
44224422
if (tok->scope()) {
44234423
lastScope = tok->scope();
4424-
if (tok == lastScope->bodyEnd && lastScope->nestedIn)
4424+
// a namespace can consist of multiple blocks and bodyStart/bodyEnd only track the
4425+
// latest block - so for namespaces any closing brace with the namespace scope closes it
4426+
if (lastScope->nestedIn &&
4427+
(tok == lastScope->bodyEnd || (tok->str() == "}" && lastScope->type == ScopeType::eNamespace)))
44254428
lastScope = lastScope->nestedIn;
44264429
} else if (lastScope)
44274430
tok->scope(lastScope);

test/testsimplifytemplate.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ class TestSimplifyTemplate : public TestFixture {
301301
TEST_CASE(templateTypeDeduction13); // members declared after the member function are visible
302302
TEST_CASE(templateTypeDeduction14); // a non template overload might be a better match
303303
TEST_CASE(templateTypeDeduction15); // final classes
304+
TEST_CASE(templateTypeDeduction16); // template between two blocks of the same namespace
304305
TEST_CASE(templateTypeDeductionFullRebuild); // --template-full-rebuild gives the same result
305306

306307
TEST_CASE(simplifyTemplateArgs1);
@@ -6918,6 +6919,22 @@ class TestSimplifyTemplate : public TestFixture {
69186919
}
69196920
}
69206921

6922+
void templateTypeDeduction16()
6923+
{ // the declaration that replaces a template between two blocks of the same namespace
6924+
// must be added to the enclosing scope - a namespace consists of multiple blocks and
6925+
// bodyStart/bodyEnd only track the latest one
6926+
const char code[] = "namespace N { struct A {}; }\n"
6927+
"template<class T> T* def(T* p, T* d) { return p ? p : d; }\n"
6928+
"namespace N { struct B {}; }\n"
6929+
"const char* f(const char* p) { return def(p, \"\"); }";
6930+
const char exp[] = "namespace N { struct A { } ; } "
6931+
"const char * def<constchar> ( const char * p , const char * d ) ; "
6932+
"namespace N { struct B { } ; } "
6933+
"const char * f ( const char * p ) { return def<constchar> ( p , \"\" ) ; } "
6934+
"const char * def<constchar> ( const char * p , const char * d ) { return p ? p : d ; }";
6935+
ASSERT_EQUALS(exp, tok(code));
6936+
}
6937+
69216938
void templateTypeDeductionFullRebuild()
69226939
{ // --template-full-rebuild recreates the symbol database etc. after each type
69236940
// deduction round instead of updating them incrementally - the result must be

0 commit comments

Comments
 (0)