@@ -317,6 +317,31 @@ class CPPCHECKLIB TemplateSimplifier {
317317 */
318318 void simplifyTemplates (std::time_t maxtime);
319319
320+ /* *
321+ * Simplify templates again, using type information (AST, SymbolDatabase, ValueType)
322+ * to deduce the template arguments of function template calls such as "f(x)",
323+ * "f(x+y)" or "f(x.g())" from the types of the argument expressions.
324+ * @param maxtime time when the simplification should be stopped
325+ * @return true if the token list was changed
326+ */
327+ bool simplifyTemplatesUsingTypeInformation (std::time_t maxtime);
328+
329+ /* *
330+ * @return true when there are function template calls where the template arguments
331+ * could not be deduced yet but deduction may succeed once type information is
332+ * available (see simplifyTemplatesUsingTypeInformation).
333+ */
334+ bool hasPendingTypeDeductions () const {
335+ return mPendingTypeDeductions ;
336+ }
337+
338+ /* *
339+ * Remove the instantiated function template declarations whose removal was deferred
340+ * while type deductions were pending.
341+ * @return true if any tokens were removed
342+ */
343+ bool removeDeferredTemplateDeclarations ();
344+
320345 /* *
321346 * Simplify constant calculations such as "1+2" => "3"
322347 * @param tok start token
@@ -353,6 +378,29 @@ class CPPCHECKLIB TemplateSimplifier {
353378 */
354379 void addInstantiation (Token *token, const std::string &scope);
355380
381+ /* *
382+ * Deduce the template arguments of a function template call from the function
383+ * arguments and insert them after the name token: "f ( 1 )" => "f < int > ( 1 )".
384+ * Literal arguments are always handled; arbitrary argument expressions are handled
385+ * when type information is available (mUseTypeInformation). Sets
386+ * mPendingTypeDeductions when a deduction could succeed later with type information.
387+ * @param tok name token of the function call
388+ * @param qualification qualification of the call ("A :: B" for "A :: B :: f ( 1 )")
389+ * @param scopeName name of the scope the call is in
390+ * @param functionNameMap map with all function template declarations
391+ */
392+ void deduceFunctionTemplateArguments (Token* tok,
393+ std::string& qualification,
394+ const std::string& scopeName,
395+ const std::multimap<std::string, const TokenAndName*>& functionNameMap);
396+
397+ /* *
398+ * Remember that the given instantiated function template declaration should not be
399+ * removed from the token list yet because pending type deductions may instantiate
400+ * it again. It is removed later by removeDeferredTemplateDeclarations().
401+ */
402+ void deferRemoval (Token* declTok);
403+
356404 /* *
357405 * Get template instantiations
358406 */
@@ -509,6 +557,17 @@ class CPPCHECKLIB TemplateSimplifier {
509557 const Settings &mSettings ;
510558 ErrorLogger &mErrorLogger ;
511559 bool mChanged {};
560+ /* * true when type information (AST, SymbolDatabase, ValueType) is available for deduction */
561+ bool mUseTypeInformation {};
562+ /* * true when there are calls where deduction may succeed once type information is available */
563+ bool mPendingTypeDeductions {};
564+ /* * true when the current simplifyTemplatesUsingTypeInformation() call deduced something */
565+ bool mTypeDeductionsMade {};
566+ /* * names of all expanded instantiations; persists between simplifyTemplates() calls so a
567+ * later deduced instantiation reuses the existing expansion instead of duplicating it */
568+ std::set<std::string> mExpandedTemplateNames ;
569+ /* * instantiated function template declarations whose removal has been deferred */
570+ std::vector<Token*> mDeferredRemovals ;
512571
513572 std::list<TokenAndName> mTemplateDeclarations ;
514573 std::list<TokenAndName> mTemplateForwardDeclarations ;
0 commit comments