[cfe-dev] MatchFinder returning many duplicate matches
Whisperity via cfe-dev
cfe-dev at lists.llvm.org
Tue Nov 19 22:56:45 PST 2019
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:
template <int i> f() {}
There is a big distinction in the language's wording that X-templates are
not Xs, only their instantiations are.
You could try using functionTemplateDecl() for the match. If I understand
this correctly, it'll give you the primary templates.
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.
>From a glance or two I've no idea why your current matcher seems to spew
out a lot of nodes still.
;;
;; Whisperity.
On Tue, 19 Nov 2019, 08:56 E via cfe-dev, <cfe-dev at lists.llvm.org> wrote:
> 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.
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20191120/d45f443e/attachment.html>
More information about the cfe-dev
mailing list