Template argument deduction using SymbolDatabase#8720
Open
pfultz2 wants to merge 14 commits into
Open
Conversation
added 11 commits
July 9, 2026 14:17
| 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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This creates a loop where we run the TemplateSimplifier -> varids/links/AST/SymbolDatabase/ValueTypes, so on the second round of
TemplateSimplifierwe can use type information from theSymbolDatabase. Not all the passes need to run withTemplateSimpliferso there is aSymbolDatabase::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-limitedsetValueTypeInTokenList()andfindAllScopes(const Token* startToken, const Token* endToken, Scope* startScope). Also thecreateSymbolDatabaseFindAllScopesinternals 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, whichupdateFunctionAndVariablePointers()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-rebuildso we can debug any issue with the incremental updates.