Skip to content

Template argument deduction using SymbolDatabase#8720

Open
pfultz2 wants to merge 14 commits into
cppcheck-opensource:mainfrom
pfultz2:template-deduce-loop
Open

Template argument deduction using SymbolDatabase#8720
pfultz2 wants to merge 14 commits into
cppcheck-opensource:mainfrom
pfultz2:template-deduce-loop

Conversation

@pfultz2

@pfultz2 pfultz2 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

This creates a loop where we run the TemplateSimplifier -> varids/links/AST/SymbolDatabase/ValueTypes, so on the second round of TemplateSimplifier we can use type information from the SymbolDatabase. Not all the passes need to run with TemplateSimplifer so there is a SymbolDatabase::finalize().

On a naive run, it would delete all the AST/SymbolDatabase information, but this can be kind of slow. So I added some incremental updates by tracking where new tokens are added(plus the function bodies around changed call sites), and then refactoring functions to work on token ranges, so there is now TokenList::createAst(start, end) and in SymbolDatabase: addSymbolsForNewTokenRanges(), updateFunctionAndVariablePointers(), a range-limited setValueTypeInTokenList() and findAllScopes(const Token* startToken, const Token* endToken, Scope* startScope). Also the createSymbolDatabaseFindAllScopes internals were split into reusable per-scope/per-function helpers to support this.

Now this only does incremental updates on function instantiation because its much simpler to do as it only adds a Function, its scope and locals(and the only stale references in old code are the renamed call sites, which updateFunctionAndVariablePointers() re-resolves by name). Instantiating a class introduces new functions and types that could be resolved in other parts of the code. So for this case it does a full rebuild.

Also the template alias simplifications requires a full build as well as it restructures existing tokens throughout the list, not just in new ranges. So the "unchanged tokens keep valid info" premise of the incremental update no longer holds.

We can probably address these in the future but will require a larger refactor. I also added a --template-full-rebuild so we can debug any issue with the incremental updates.

MathLib::value num(arg->str());
if (num.isFloat()) {
// MathLib::getSuffix doesn't work for floating point numbers
const char suffix = arg->str().back();
if (it != parameterCountCache.cend())
return it->second;
const DeductionCandidate parsed = parseDeductionCandidate(candidate);
const int count = parsed.typeParameters.empty() ? -1 : static_cast<int>(parsed.parameterShapes.size());
// matching is not possible yet - the declaration may be in a base class - so
// consider all declarations with this name.
for (auto pos = range.first; pos != range.second; ++pos) {
if (supportedParameterCount(*pos->second) == static_cast<int>(instantiationArgs.size())) {
const TokenAndName* declaration = nullptr;
DeductionCandidate parsedDeclaration;
for (const TokenAndName* candidate : candidates) {
if (supportedParameterCount(*candidate) != static_cast<int>(instantiationArgs.size()))
// "T *": the argument must be a pointer and T is the pointee type
if (pointer < 1)
return DeducedType();
constness &= ~(1U << pointer);

if (pointer > 2)
return DeducedType();
if (constness >= (1U << (pointer + 1)))
case ValueType::UNKNOWN_INT:
// not deducible
return DeducedType();
}
static void insertDeducedType(Token* tok, const DeducedType& deduced)
{
for (int level = deduced.pointer; level >= 1; --level) {
if (deduced.constness & (1U << level))
std::vector<const Token*> declarationParams;
getFunctionArguments(candidate.nameToken(), declarationParams);

std::vector<bool> deducible(parsed.typeParameters.size(), false);
if (argRoots.size() != instantiationArgs.size())
return qualification;
std::vector<DeducedType> deducedTypes(parsedDeclaration.typeParameters.size());
std::vector<bool> deducedSet(parsedDeclaration.typeParameters.size(), false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants