Skip to content

Commit 865f0aa

Browse files
author
Your Name
committed
Simplify
1 parent 0ce48a0 commit 865f0aa

5 files changed

Lines changed: 179 additions & 213 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 97 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -963,23 +963,26 @@ void SymbolDatabase::createSymbolDatabaseClassAndStructScopes()
963963
}
964964
}
965965

966+
void SymbolDatabase::setFunctionReturnType(Function& function, const Scope& scope) const
967+
{
968+
if (!function.retDef)
969+
return;
970+
const Token *type = function.retDef;
971+
while (Token::Match(type, "static|const|struct|union|enum"))
972+
type = type->next();
973+
if (type) {
974+
function.retType = findVariableTypeInBase(&scope, type);
975+
if (!function.retType)
976+
function.retType = findTypeInNested(type, function.nestedIn);
977+
}
978+
}
979+
966980
void SymbolDatabase::createSymbolDatabaseFunctionReturnTypes()
967981
{
968982
// fill in function return types
969983
for (Scope& scope : scopeList) {
970-
for (auto func = scope.functionList.begin(); func != scope.functionList.end(); ++func) {
971-
// add return types
972-
if (func->retDef) {
973-
const Token *type = func->retDef;
974-
while (Token::Match(type, "static|const|struct|union|enum"))
975-
type = type->next();
976-
if (type) {
977-
func->retType = findVariableTypeInBase(&scope, type);
978-
if (!func->retType)
979-
func->retType = findTypeInNested(type, func->nestedIn);
980-
}
981-
}
982-
}
984+
for (Function& function : scope.functionList)
985+
setFunctionReturnType(function, scope);
983986
}
984987
}
985988

@@ -1084,69 +1087,79 @@ void SymbolDatabase::createSymbolDatabaseNeedInitialization()
10841087
}
10851088
}
10861089

1087-
void SymbolDatabase::createSymbolDatabaseVariableSymbolTable()
1090+
void SymbolDatabase::addVariablesToSymbolTable(Scope& scope)
10881091
{
1089-
// create variable symbol table
1090-
mVariableList.resize(mTokenizer.varIdCount() + 1);
1091-
std::fill_n(mVariableList.begin(), mVariableList.size(), nullptr);
1092+
for (Variable& var: scope.varlist) {
1093+
const int varId = var.declarationId();
1094+
if (varId)
1095+
mVariableList[varId] = &var;
1096+
// fix up variables without type
1097+
if (!var.type() && !var.typeStartToken()->isStandardType()) {
1098+
const Type *type = findType(var.typeStartToken(), &scope);
1099+
if (type)
1100+
var.type(type);
1101+
}
1102+
}
1103+
}
10921104

1093-
// check all scopes for variables
1094-
for (Scope& scope : scopeList) {
1095-
// add all variables
1096-
for (Variable& var: scope.varlist) {
1097-
const int varId = var.declarationId();
1098-
if (varId)
1099-
mVariableList[varId] = &var;
1100-
// fix up variables without type
1101-
if (!var.type() && !var.typeStartToken()->isStandardType()) {
1102-
const Type *type = findType(var.typeStartToken(), &scope);
1105+
void SymbolDatabase::addArgumentsToSymbolTable(Function& function, const Scope& scope)
1106+
{
1107+
for (Variable& arg: function.argumentList) {
1108+
// check for named parameters
1109+
if (arg.nameToken() && arg.declarationId()) {
1110+
const int declarationId = arg.declarationId();
1111+
mVariableList[declarationId] = &arg;
1112+
// fix up parameters without type
1113+
if (!arg.type() && !arg.typeStartToken()->isStandardType()) {
1114+
const Type *type = findTypeInNested(arg.typeStartToken(), &scope);
11031115
if (type)
1104-
var.type(type);
1116+
arg.type(type);
11051117
}
11061118
}
1119+
}
1120+
}
11071121

1108-
// add all function parameters
1109-
for (Function& func : scope.functionList) {
1110-
for (Variable& arg: func.argumentList) {
1111-
// check for named parameters
1112-
if (arg.nameToken() && arg.declarationId()) {
1113-
const int declarationId = arg.declarationId();
1114-
mVariableList[declarationId] = &arg;
1115-
// fix up parameters without type
1116-
if (!arg.type() && !arg.typeStartToken()->isStandardType()) {
1117-
const Type *type = findTypeInNested(arg.typeStartToken(), &scope);
1118-
if (type)
1119-
arg.type(type);
1120-
}
1122+
void SymbolDatabase::fillMissingVariables(const Scope& functionScope)
1123+
{
1124+
for (const Token *tok = functionScope.bodyStart->next(); tok && tok != functionScope.bodyEnd; tok = tok->next()) {
1125+
// check for member variable
1126+
if (!Token::Match(tok, "%var% .|["))
1127+
continue;
1128+
const Token* tokDot = tok->next();
1129+
while (Token::simpleMatch(tokDot, "["))
1130+
tokDot = tokDot->link()->next();
1131+
if (!Token::Match(tokDot, ". %var%"))
1132+
continue;
1133+
const Token *member = tokDot->next();
1134+
if (mVariableList[member->varId()] == nullptr) {
1135+
const Variable *var1 = mVariableList[tok->varId()];
1136+
if (var1 && var1->typeScope()) {
1137+
const Variable* memberVar = var1->typeScope()->getVariable(member->str());
1138+
if (memberVar) {
1139+
// add this variable to the look up table
1140+
mVariableList[member->varId()] = memberVar;
11211141
}
11221142
}
11231143
}
11241144
}
1145+
}
11251146

1126-
// fill in missing variables if possible
1127-
for (const Scope *func: functionScopes) {
1128-
for (const Token *tok = func->bodyStart->next(); tok && tok != func->bodyEnd; tok = tok->next()) {
1129-
// check for member variable
1130-
if (!Token::Match(tok, "%var% .|["))
1131-
continue;
1132-
const Token* tokDot = tok->next();
1133-
while (Token::simpleMatch(tokDot, "["))
1134-
tokDot = tokDot->link()->next();
1135-
if (!Token::Match(tokDot, ". %var%"))
1136-
continue;
1137-
const Token *member = tokDot->next();
1138-
if (mVariableList[member->varId()] == nullptr) {
1139-
const Variable *var1 = mVariableList[tok->varId()];
1140-
if (var1 && var1->typeScope()) {
1141-
const Variable* memberVar = var1->typeScope()->getVariable(member->str());
1142-
if (memberVar) {
1143-
// add this variable to the look up table
1144-
mVariableList[member->varId()] = memberVar;
1145-
}
1146-
}
1147-
}
1148-
}
1147+
void SymbolDatabase::createSymbolDatabaseVariableSymbolTable()
1148+
{
1149+
// create variable symbol table
1150+
mVariableList.resize(mTokenizer.varIdCount() + 1);
1151+
std::fill_n(mVariableList.begin(), mVariableList.size(), nullptr);
1152+
1153+
// check all scopes for variables and function parameters
1154+
for (Scope& scope : scopeList) {
1155+
addVariablesToSymbolTable(scope);
1156+
for (Function& function : scope.functionList)
1157+
addArgumentsToSymbolTable(function, scope);
11491158
}
1159+
1160+
// fill in missing variables if possible
1161+
for (const Scope *func: functionScopes)
1162+
fillMissingVariables(*func);
11501163
}
11511164

11521165
void SymbolDatabase::createSymbolDatabaseSetScopePointers()
@@ -1498,6 +1511,10 @@ void SymbolDatabase::createSymbolDatabaseEnums()
14981511

14991512
// find enumerators
15001513
for (Token* tok = mTokenizer.list.front(); tok != mTokenizer.list.back(); tok = tok->next()) {
1514+
// an eEnumerator token without an enumerator is a copy that the template
1515+
// simplifier made of an already resolved token - resolve it again
1516+
if (tok->tokType() == Token::eEnumerator && !tok->enumerator())
1517+
tok->tokType(Token::eName);
15011518
const bool isVariable = (tok->tokType() == Token::eVariable && !tok->variable());
15021519
if (tok->tokType() != Token::eName && !isVariable)
15031520
continue;
@@ -1856,29 +1873,19 @@ void SymbolDatabase::createSymbolDatabaseExprIds()
18561873
}
18571874
}
18581875

1859-
void SymbolDatabase::removeSymbolsInTokenRanges(const std::vector<std::pair<Token*, const Token*>>& ranges)
1876+
void SymbolDatabase::removeSymbolsForTokens(const std::unordered_set<const Token*>& removedTokens)
18601877
{
1861-
if (ranges.empty())
1878+
if (removedTokens.empty())
18621879
return;
18631880

1864-
// all tokens that are going to be removed
1865-
std::set<const Token*> removedTokens;
1866-
for (const auto& range : ranges) {
1867-
for (const Token* tok = range.first; tok; tok = tok->next()) {
1868-
removedTokens.insert(tok);
1869-
if (tok == range.second)
1870-
break;
1871-
}
1872-
}
1873-
18741881
// the scopes, functions, variables, types and enumerators declared by those tokens
1875-
std::set<const Scope*> removedScopes;
1882+
std::unordered_set<const Scope*> removedScopes;
18761883
for (const Scope& scope : scopeList) {
18771884
if ((scope.classDef && removedTokens.count(scope.classDef) != 0) ||
18781885
(scope.bodyStart && removedTokens.count(scope.bodyStart) != 0))
18791886
removedScopes.insert(&scope);
18801887
}
1881-
std::set<const Function*> removedFunctions;
1888+
std::unordered_set<const Function*> removedFunctions;
18821889
for (Scope& scope : scopeList) {
18831890
for (Function& function : scope.functionList) {
18841891
if (function.tokenDef && removedTokens.count(function.tokenDef) != 0)
@@ -1892,7 +1899,7 @@ void SymbolDatabase::removeSymbolsInTokenRanges(const std::vector<std::pair<Toke
18921899
}
18931900
}
18941901
}
1895-
std::set<const Variable*> removedVariables;
1902+
std::unordered_set<const Variable*> removedVariables;
18961903
for (const Scope* scope : removedScopes) {
18971904
std::transform(scope->varlist.cbegin(), scope->varlist.cend(), std::inserter(removedVariables, removedVariables.end()), [](const Variable& var) {
18981905
return &var;
@@ -1903,12 +1910,12 @@ void SymbolDatabase::removeSymbolsInTokenRanges(const std::vector<std::pair<Toke
19031910
return &arg;
19041911
});
19051912
}
1906-
std::set<const Type*> removedTypes;
1913+
std::unordered_set<const Type*> removedTypes;
19071914
for (const Type& type : typeList) {
19081915
if (type.classDef && removedTokens.count(type.classDef) != 0)
19091916
removedTypes.insert(&type);
19101917
}
1911-
std::set<const Enumerator*> removedEnumerators;
1918+
std::unordered_set<const Enumerator*> removedEnumerators;
19121919
for (const Scope* scope : removedScopes) {
19131920
std::transform(scope->enumeratorList.cbegin(), scope->enumeratorList.cend(), std::inserter(removedEnumerators, removedEnumerators.end()), [](const Enumerator& enumerator) {
19141921
return &enumerator;
@@ -1985,7 +1992,7 @@ void SymbolDatabase::addSymbolsForNewTokenRanges(const std::vector<std::pair<Tok
19851992
const std::size_t oldScopeCount = scopeList.size();
19861993

19871994
// all new tokens - the new functions are found through them afterwards
1988-
std::set<const Token*> newTokens;
1995+
std::unordered_set<const Token*> newTokens;
19891996
for (const auto& range : newRanges) {
19901997
for (const Token* tok = range.first; tok; tok = tok->next()) {
19911998
newTokens.insert(tok);
@@ -2032,16 +2039,7 @@ void SymbolDatabase::addSymbolsForNewTokenRanges(const std::vector<std::pair<Tok
20322039
for (const auto& f : newFunctions) {
20332040
if (f.first->argumentList.empty())
20342041
f.first->addArguments(f.second);
2035-
if (f.first->retDef) {
2036-
const Token *type = f.first->retDef;
2037-
while (Token::Match(type, "static|const|struct|union|enum"))
2038-
type = type->next();
2039-
if (type) {
2040-
f.first->retType = findVariableTypeInBase(f.second, type);
2041-
if (!f.first->retType)
2042-
f.first->retType = findTypeInNested(type, f.first->nestedIn);
2043-
}
2044-
}
2042+
setFunctionReturnType(*f.first, *f.second);
20452043
}
20462044

20472045
// fast access vectors
@@ -2055,57 +2053,14 @@ void SymbolDatabase::addSymbolsForNewTokenRanges(const std::vector<std::pair<Tok
20552053
// variable symbol table: add the new variables (incremental version of
20562054
// createSymbolDatabaseVariableSymbolTable)
20572055
mVariableList.resize(mTokenizer.varIdCount() + 1);
2058-
for (Scope* scope : newScopes) {
2059-
for (Variable& var : scope->varlist) {
2060-
const int varId = var.declarationId();
2061-
if (varId)
2062-
mVariableList[varId] = &var;
2063-
// fix up variables without type
2064-
if (!var.type() && !var.typeStartToken()->isStandardType()) {
2065-
const Type *type = findType(var.typeStartToken(), scope);
2066-
if (type)
2067-
var.type(type);
2068-
}
2069-
}
2070-
}
2071-
for (const auto& f : newFunctions) {
2072-
for (Variable& arg : f.first->argumentList) {
2073-
if (arg.nameToken() && arg.declarationId()) {
2074-
mVariableList[arg.declarationId()] = &arg;
2075-
// fix up parameters without type
2076-
if (!arg.type() && !arg.typeStartToken()->isStandardType()) {
2077-
const Type *type = findTypeInNested(arg.typeStartToken(), f.second);
2078-
if (type)
2079-
arg.type(type);
2080-
}
2081-
}
2082-
}
2083-
}
2056+
for (Scope* scope : newScopes)
2057+
addVariablesToSymbolTable(*scope);
2058+
for (const auto& f : newFunctions)
2059+
addArgumentsToSymbolTable(*f.first, *f.second);
20842060
// fill in missing variables in the new code if possible
2085-
for (const Scope* func : newScopes) {
2086-
if (func->type != ScopeType::eFunction)
2087-
continue;
2088-
for (const Token *tok = func->bodyStart->next(); tok && tok != func->bodyEnd; tok = tok->next()) {
2089-
// check for member variable
2090-
if (!Token::Match(tok, "%var% .|["))
2091-
continue;
2092-
const Token* tokDot = tok->next();
2093-
while (Token::simpleMatch(tokDot, "["))
2094-
tokDot = tokDot->link()->next();
2095-
if (!Token::Match(tokDot, ". %var%"))
2096-
continue;
2097-
const Token *member = tokDot->next();
2098-
if (mVariableList[member->varId()] == nullptr) {
2099-
const Variable *var1 = mVariableList[tok->varId()];
2100-
if (var1 && var1->typeScope()) {
2101-
const Variable* memberVar = var1->typeScope()->getVariable(member->str());
2102-
if (memberVar) {
2103-
// add this variable to the look up table
2104-
mVariableList[member->varId()] = memberVar;
2105-
}
2106-
}
2107-
}
2108-
}
2061+
for (const Scope* scope : newScopes) {
2062+
if (scope->type == ScopeType::eFunction)
2063+
fillMissingVariables(*scope);
21092064
}
21102065

21112066
// set the definition and declaration pointers of the new functions. The call

lib/symboldatabase.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <map>
3939
#include <set>
4040
#include <string>
41+
#include <unordered_set>
4142
#include <utility>
4243
#include <vector>
4344

@@ -1439,12 +1440,12 @@ class CPPCHECKLIB SymbolDatabase {
14391440
void createSymbolDatabaseExprIds();
14401441

14411442
/**
1442-
* Remove the symbols (scopes, functions, variables, types) that are declared in the
1443-
* given token ranges (both range ends are inclusive) and clear the references to
1444-
* them. Called before the tokens are removed from the token list, e.g. when the
1445-
* template simplifier removes instantiated template declarations.
1443+
* Remove the symbols (scopes, functions, variables, types) that are declared by the
1444+
* given tokens and clear the references to them. Called before the tokens are
1445+
* removed from the token list, e.g. when the template simplifier removes
1446+
* instantiated template declarations.
14461447
*/
1447-
void removeSymbolsInTokenRanges(const std::vector<std::pair<Token*, const Token*>>& ranges);
1448+
void removeSymbolsForTokens(const std::unordered_set<const Token*>& removedTokens);
14481449

14491450
/**
14501451
* Add the symbols for token ranges (both range ends are inclusive) that were added
@@ -1492,6 +1493,15 @@ class CPPCHECKLIB SymbolDatabase {
14921493
void createSymbolDatabaseFunctionScopes();
14931494
void createSymbolDatabaseClassAndStructScopes();
14941495
void createSymbolDatabaseFunctionReturnTypes();
1496+
/** fill in the return type of one function (used by the full build and by
1497+
* addSymbolsForNewTokenRanges) */
1498+
void setFunctionReturnType(Function& function, const Scope& scope) const;
1499+
/** add the variables of one scope to the variable symbol table */
1500+
void addVariablesToSymbolTable(Scope& scope);
1501+
/** add the parameters of one function to the variable symbol table */
1502+
void addArgumentsToSymbolTable(Function& function, const Scope& scope);
1503+
/** fill in the missing member variables in one function scope */
1504+
void fillMissingVariables(const Scope& functionScope);
14951505
void createSymbolDatabaseNeedInitialization();
14961506
void createSymbolDatabaseVariableSymbolTable();
14971507
void createSymbolDatabaseSetScopePointers();

0 commit comments

Comments
 (0)