For now I can get it only in MatchCallback::run(const MatchResult& r):
r.SourceManager.getFileEntryForID(r.SourceManager.getMainFileID())->getName().str()
and cache for future use. But I might need it in my MatchCallback subclass even if no matches were found in current file. It's weird that onStartOfTranslationUnit() does not give a clue which translation unit is started.
Not easily
Unfortunately, there isn't an easy way to get the main file from the
onStartOfTranslationUnitmethod ofMatchCallback. The call site is inclang/lib/ASTMatchers/ASTMatchFinder.cpp:The caller has access to an
ASTContextin itsActiveASTContextmember, from which we could easily get the main source file, but it chooses not to pass it.Workaround: Intercepting at a higher level
Assuming you're using
MatchCallbackin a way similar to the tutorials, somewhere you are making aMatchFinderobject and usingaddMatcherto arrange for it to call your callback methods, something like:In this construction,
MatchFinder::newASTConsumerwill be called, which makes an intermediate object of typeMatchASTConsumer(which is private to the implementation), which invokes theMatchCallbackmethods.To insert additional processing into this chain, we need to:
Define
MyMatchFinderwhosenewASTConsumercreates aMyMatchASTConsumer.Define
MyMatchASTConsumerwhoseHandleTranslationUnitmethod callsMyMatchFinder::matchAST.Define
MyMatchFinder::matchAST, which calls a newonTUcallback that accepts anASTContext. This requires thatMyMatchFindercarry its own pointer to the callbacks object.Define and use the
onTUcallback instead of the oldonStartOfTranslationUnit.Create a
MyMatchFinderand pass that toToolinstead.Complete example
The following files provide a complete example demonstrating the approach.
ast-match-finder.cc:Makefile:test.cc:test2.cc:Example run:
Observe that we see both TUs, each with a match on a distinct line.