[cfe-dev] MatchFinder returning many duplicate matches
E via cfe-dev
cfe-dev at lists.llvm.org
Mon Nov 18 23:56:08 PST 2019
Hello,
I have a tool that runs over all TUs in a project and matches all function declarations.
These declarations are then stored in a database for later processing.
My problem is that the MatchFinder callback returns many duplicates of the same
function, probably due to the use of templates in the function decl.
I've provided a sample of duplicate USRs for the from_json function in a test project.
from_json c:@N at nlohmann@S at adl_serializer>#{n5C#v at FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S
from_json c:@N at nlohmann@S at adl_serializer>#{n6C#v at FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S
from_json c:@N at nlohmann@S at adl_serializer>#*1C#v at FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S
from_json c:@N at nlohmann@S at adl_serializer>#{n7C#v at FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S
from_json c:@N at nlohmann@S at adl_serializer>#{n10C#v at FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S
from_json c:@N at nlohmann@S at adl_serializer>#{n8C#v at FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S
from_json c:@N at nlohmann@S at adl_serializer>#b#v at FT@>2#T#Tfrom_json#&&t0.0#&t0.1# #S
Based on the USRs, it seems like the MatchFinder considers each template instantiation
a separate declaration, whereas I'd like it to return a single function decl that is templated.
Is there a way to eliminate these duplicates during the matching stage?
I have attached a minimal code example below.
class FunctionMatcher : public MatchFinder::MatchCallback {
public:
FunctionMatcher() {}
DeclarationMatcher matcher = functionDecl(unless(anyOf(isDefinition(),
isImplicit(),
isInStdNamespace(),
isExpansionInSystemHeader(),
isTemplateInstantiation(),
isExplicitTemplateSpecialization())))
.bind("function");
virtual void run(const MatchFinder::MatchResult& Result) {
auto res = Result.Nodes.getNodeAs<clang::FunctionDecl>("function");
// Ignore invalid matches
if (res == nullptr) {
return;
}
// Print function name and USR
llvm::SmallString<128> USR;
if (!clang::index::generateUSRForDecl(d, USR)) {
printf("%s %s\n", res->getNameAsString().c_str(), USR.str().c_str());
}
}
}
int main() {
FunctionMatcher FunctionFinder(&this->index, this->cfg);
clang::ast_matchers::MatchFinder Finder;
Finder.addMatcher(FunctionFinder.matcher, &FunctionFinder);
auto cmpdb = clang::tooling::CompilationDatabase::loadFromDirectory("test", "err_msg");
clang::tooling::ClangTool t(*cmpdb, cmpdb->getAllFiles());
t.run(clang::tooling::newFrontendActionFactory(&Finder).get());
}
Thanks.
More information about the cfe-dev
mailing list