-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang-tidy] Avoid processing declarations in system headers #128150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
#include <deque> | ||
#include <memory> | ||
#include <set> | ||
#include <vector> | ||
|
||
namespace clang { | ||
namespace ast_matchers { | ||
|
@@ -422,7 +423,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, | |
public ASTMatchFinder { | ||
public: | ||
MatchASTVisitor(const MatchFinder::MatchersByType *Matchers, | ||
const MatchFinder::MatchFinderOptions &Options) | ||
const MatchFinderOptions &Options) | ||
: Matchers(Matchers), Options(Options), ActiveASTContext(nullptr) {} | ||
|
||
~MatchASTVisitor() override { | ||
|
@@ -1350,7 +1351,7 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, | |
/// We precalculate a list of matchers that pass the toplevel restrict check. | ||
llvm::DenseMap<ASTNodeKind, std::vector<unsigned short>> MatcherFiltersMap; | ||
|
||
const MatchFinder::MatchFinderOptions &Options; | ||
const MatchFinderOptions &Options; | ||
ASTContext *ActiveASTContext; | ||
|
||
// Maps a canonical type to its TypedefDecls. | ||
|
@@ -1573,19 +1574,41 @@ bool MatchASTVisitor::TraverseAttr(Attr *AttrNode) { | |
class MatchASTConsumer : public ASTConsumer { | ||
public: | ||
MatchASTConsumer(MatchFinder *Finder, | ||
MatchFinder::ParsingDoneTestCallback *ParsingDone) | ||
: Finder(Finder), ParsingDone(ParsingDone) {} | ||
MatchFinder::ParsingDoneTestCallback *ParsingDone, | ||
const MatchFinderOptions &Options) | ||
: Finder(Finder), ParsingDone(ParsingDone), Options(Options) {} | ||
|
||
private: | ||
bool HandleTopLevelDecl(DeclGroupRef DG) override { | ||
if (Options.SkipSystemHeaders) { | ||
for (Decl *D : DG) { | ||
if (!isInSystemHeader(D)) | ||
TraversalScope.push_back(D); | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
void HandleTranslationUnit(ASTContext &Context) override { | ||
if (!TraversalScope.empty()) | ||
Context.setTraversalScope(TraversalScope); | ||
Comment on lines
+1593
to
+1594
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This mean that if .cpp file is empty, then we will traverse system headers includes regardless of SkipSystemHeaders. By default TraversalScope in Context is set to TranslationUnit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, that's correct. I thought about that, but I envision we will add more boolean options to skip more things, like PCH, modules, HeaderFilter, etc. So I thought the This would be a problem only if we parse an empty file with only system includes. Is that a common use case? |
||
|
||
if (ParsingDone != nullptr) { | ||
ParsingDone->run(); | ||
} | ||
Finder->matchAST(Context); | ||
} | ||
|
||
bool isInSystemHeader(Decl *D) { | ||
const SourceManager &SM = D->getASTContext().getSourceManager(); | ||
const SourceLocation Loc = SM.getExpansionLoc(D->getBeginLoc()); | ||
return SM.isInSystemHeader(Loc); | ||
} | ||
|
||
MatchFinder *Finder; | ||
MatchFinder::ParsingDoneTestCallback *ParsingDone; | ||
const MatchFinderOptions &Options; | ||
std::vector<Decl *> TraversalScope; | ||
}; | ||
|
||
} // end namespace | ||
|
@@ -1704,7 +1727,8 @@ bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, | |
} | ||
|
||
std::unique_ptr<ASTConsumer> MatchFinder::newASTConsumer() { | ||
return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone); | ||
return std::make_unique<internal::MatchASTConsumer>(this, ParsingDone, | ||
Options); | ||
} | ||
|
||
void MatchFinder::match(const clang::DynTypedNode &Node, ASTContext &Context) { | ||
|
Uh oh!
There was an error while loading. Please reload this page.