1 #include "AssertCheck.h"
2
3 #include <unordered_set>
4
5 #include "clang/Frontend/CompilerInstance.h"
6
7 using namespace clang::ast_matchers;
8
9 namespace clang
10 {
11 namespace tidy
12 {
13 namespace cata
14 {
15
16 class AssertMacroCallbacks : public PPCallbacks
17 {
18 public:
AssertMacroCallbacks(Preprocessor * PP,AssertCheck * Check)19 AssertMacroCallbacks( Preprocessor *PP, AssertCheck *Check ) :
20 PP( PP ), Check( Check ) {}
21
MacroExpands(const Token & MacroNameTok,const MacroDefinition &,SourceRange Range,const MacroArgs *)22 void MacroExpands( const Token &MacroNameTok,
23 const MacroDefinition &,
24 SourceRange Range,
25 const MacroArgs * ) override {
26 StringRef MacroName = MacroNameTok.getIdentifierInfo()->getName();
27 SourceLocation Begin = Range.getBegin();
28 SourceManager &SM = PP->getSourceManager();
29 // When using assert inside cata_assert, this fetches the location
30 // of the cata_assert from that of the assert.
31 SourceLocation ExpansionBegin = SM.getFileLoc( Begin );
32 if( MacroName == "cata_assert" ) {
33 CataAssertLocations.insert( ExpansionBegin );
34 } else if( MacroName == "assert" ) {
35 if( !CataAssertLocations.count( ExpansionBegin ) ) {
36 SourceRange RangeToReplace(
37 Begin, Begin.getLocWithOffset( MacroName.size() - 1 ) );
38 Check->diag( Begin, "Prefer cata_assert to assert." ) <<
39 FixItHint::CreateReplacement( RangeToReplace, "cata_assert" );
40 }
41 }
42 }
43 private:
44 Preprocessor *PP;
45 AssertCheck *Check;
46 llvm::SmallPtrSet<SourceLocation, 10> CataAssertLocations;
47 };
48
registerPPCallbacks(CompilerInstance & Compiler)49 void AssertCheck::registerPPCallbacks( CompilerInstance &Compiler )
50 {
51 Compiler.getPreprocessor().addPPCallbacks(
52 llvm::make_unique<AssertMacroCallbacks>( &Compiler.getPreprocessor(), this ) );
53 }
54
registerMatchers(MatchFinder *)55 void AssertCheck::registerMatchers( MatchFinder * /*Finder*/ )
56 {
57 }
58
check(const MatchFinder::MatchResult &)59 void AssertCheck::check( const MatchFinder::MatchResult &/*Result*/ )
60 {
61 }
62
63 } // namespace cata
64 } // namespace tidy
65 } // namespace clang
66