<div dir="auto">If I understand correctly you want to return what's usually referred to as the "primary template"? The program element which is the template itself, not any instantiation:<div dir="auto"><br></div><div dir="auto"> template <int i> f() {}</div><div dir="auto"><br></div><div dir="auto">There is a big distinction in the language's wording that X-templates are not Xs, only their instantiations are.</div><div dir="auto"><br></div><div dir="auto">You could try using functionTemplateDecl() for the match. If I understand this correctly, it'll give you the primary templates.</div><div dir="auto"><br></div><div dir="auto">In case you want, apart from this, the explicit specialisations, there's a predicate isExplicitTemplateSpecialisation() which you used as a filter already. That predicate should apply to the "concrete decl" (as opposed to the template) as explicit specialisations are concrete existing code with no need to instantiate any further.</div><div dir="auto"><br></div><div dir="auto">From a glance or two I've no idea why your current matcher seems to spew out a lot of nodes still. </div><div dir="auto"><br></div><div dir="auto">;;</div><div dir="auto">;; Whisperity.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 19 Nov 2019, 08:56 E via cfe-dev, <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" rel="noreferrer">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
<br>
I have a tool that runs over all TUs in a project and matches all function declarations.<br>
These declarations are then stored in a database for later processing.<br>
<br>
My problem is that the MatchFinder callback returns many duplicates of the same<br>
function, probably due to the use of templates in the function decl.<br>
<br>
I've provided a sample of duplicate USRs for the from_json function in a test project.<br>
<br>
from_json c:@N@nlohmann@S@adl_serializer>#{n5C#v@FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S<br>
from_json c:@N@nlohmann@S@adl_serializer>#{n6C#v@FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S<br>
from_json c:@N@nlohmann@S@adl_serializer>#*1C#v@FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S<br>
from_json c:@N@nlohmann@S@adl_serializer>#{n7C#v@FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S<br>
from_json c:@N@nlohmann@S@adl_serializer>#{n10C#v@FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S<br>
from_json c:@N@nlohmann@S@adl_serializer>#{n8C#v@FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S<br>
from_json c:@N@nlohmann@S@adl_serializer>#b#v@FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S<br>
<br>
Based on the USRs, it seems like the MatchFinder considers each template instantiation<br>
a separate declaration, whereas I'd like it to return a single function decl that is templated.<br>
<br>
Is there a way to eliminate these duplicates during the matching stage?<br>
I have attached a minimal code example below.<br>
<br>
class FunctionMatcher : public MatchFinder::MatchCallback {<br>
public:<br>
FunctionMatcher() {}<br>
DeclarationMatcher matcher = functionDecl(unless(anyOf(isDefinition(),<br>
isImplicit(),<br>
isInStdNamespace(),<br>
isExpansionInSystemHeader(),<br>
isTemplateInstantiation(),<br>
isExplicitTemplateSpecialization())))<br>
.bind("function");<br>
virtual void run(const MatchFinder::MatchResult& Result) {<br>
auto res = Result.Nodes.getNodeAs<clang::FunctionDecl>("function");<br>
// Ignore invalid matches<br>
if (res == nullptr) {<br>
return;<br>
}<br>
<br>
// Print function name and USR<br>
llvm::SmallString<128> USR;<br>
if (!clang::index::generateUSRForDecl(d, USR)) {<br>
printf("%s %s\n", res->getNameAsString().c_str(), USR.str().c_str());<br>
}<br>
}<br>
<br>
}<br>
<br>
int main() {<br>
FunctionMatcher FunctionFinder(&this->index, this->cfg);<br>
clang::ast_matchers::MatchFinder Finder;<br>
Finder.addMatcher(FunctionFinder.matcher, &FunctionFinder);<br>
<br>
auto cmpdb = clang::tooling::CompilationDatabase::loadFromDirectory("test", "err_msg");<br>
clang::tooling::ClangTool t(*cmpdb, cmpdb->getAllFiles());<br>
t.run(clang::tooling::newFrontendActionFactory(&Finder).get());<br>
}<br>
<br>
Thanks.<br>
<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" rel="noreferrer noreferrer" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>