-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add custom clang-tidy check for fields that could be replaced by poin…
…ts (#32852) * Add clang-tidy check for structs with x,y members * Suppress cata-xy warnings in various places * Simplify boolean expression * Remove redundant point initialization
- Loading branch information
1 parent
f279660
commit 6e4bd90
Showing
11 changed files
with
183 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#include "XYCheck.h" | ||
|
||
#include "clang/ASTMatchers/ASTMatchFinder.h" | ||
#include "clang/Frontend/CompilerInstance.h" | ||
|
||
using namespace clang::ast_matchers; | ||
|
||
namespace clang | ||
{ | ||
namespace tidy | ||
{ | ||
namespace cata | ||
{ | ||
|
||
void XYCheck::registerMatchers( MatchFinder *Finder ) | ||
{ | ||
Finder->addMatcher( | ||
fieldDecl( | ||
hasType( asString( "int" ) ), | ||
matchesName( "x$" ), | ||
hasParent( | ||
cxxRecordDecl( | ||
forEachDescendant( fieldDecl( matchesName( "y$" ) ).bind( "yfield" ) ) | ||
).bind( "record" ) | ||
) | ||
).bind( "xfield" ), | ||
this | ||
); | ||
} | ||
|
||
static void CheckField( XYCheck &Check, const MatchFinder::MatchResult &Result ) | ||
{ | ||
const FieldDecl *XVar = Result.Nodes.getNodeAs<FieldDecl>( "xfield" ); | ||
const FieldDecl *YVar = Result.Nodes.getNodeAs<FieldDecl>( "yfield" ); | ||
const CXXRecordDecl *Record = Result.Nodes.getNodeAs<CXXRecordDecl>( "record" ); | ||
if( !XVar || !YVar || !Record ) { | ||
return; | ||
} | ||
llvm::StringRef XPrefix = XVar->getName().drop_back(); | ||
llvm::StringRef YPrefix = YVar->getName().drop_back(); | ||
if( XPrefix != YPrefix ) { | ||
return; | ||
} | ||
|
||
const FieldDecl *ZVar = nullptr; | ||
for( FieldDecl *Field : Record->fields() ) { | ||
StringRef Name = Field->getName(); | ||
if( Name.endswith( "z" ) && Name.drop_back() == XPrefix ) { | ||
ZVar = Field; | ||
break; | ||
} | ||
} | ||
TemplateSpecializationKind tsk = Record->getTemplateSpecializationKind(); | ||
if( tsk != TSK_Undeclared ) { | ||
// Avoid duplicate warnings for specializations | ||
return; | ||
} | ||
if( ZVar ) { | ||
Check.diag( | ||
Record->getLocation(), | ||
"%0 defines fields %1, %2, and %3. Consider combining into a single tripoint " | ||
"field." ) << Record << XVar << YVar << ZVar; | ||
} else { | ||
Check.diag( | ||
Record->getLocation(), | ||
"%0 defines fields %1 and %2. Consider combining into a single point " | ||
"field." ) << Record << XVar << YVar; | ||
} | ||
Check.diag( XVar->getLocation(), "declaration of %0", DiagnosticIDs::Note ) << XVar; | ||
Check.diag( YVar->getLocation(), "declaration of %0", DiagnosticIDs::Note ) << YVar; | ||
if( ZVar ) { | ||
Check.diag( ZVar->getLocation(), "declaration of %0", DiagnosticIDs::Note ) << ZVar; | ||
} | ||
} | ||
|
||
void XYCheck::check( const MatchFinder::MatchResult &Result ) | ||
{ | ||
CheckField( *this, Result ); | ||
} | ||
|
||
} // namespace cata | ||
} // namespace tidy | ||
} // namespace clang |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#ifndef CATA_TOOLS_CLANG_TIDY_XYCHECK_H | ||
#define CATA_TOOLS_CLANG_TIDY_XYCHECK_H | ||
|
||
#include <clang/ASTMatchers/ASTMatchFinder.h> | ||
#include <llvm/ADT/StringRef.h> | ||
|
||
#include "ClangTidy.h" | ||
|
||
namespace clang | ||
{ | ||
class CompilerInstance; | ||
|
||
namespace tidy | ||
{ | ||
class ClangTidyContext; | ||
|
||
namespace cata | ||
{ | ||
|
||
class XYCheck : public ClangTidyCheck | ||
{ | ||
public: | ||
XYCheck( StringRef Name, ClangTidyContext *Context ) | ||
: ClangTidyCheck( Name, Context ) {} | ||
void registerMatchers( ast_matchers::MatchFinder *Finder ) override; | ||
void check( const ast_matchers::MatchFinder::MatchResult &Result ) override; | ||
}; | ||
|
||
} // namespace cata | ||
} // namespace tidy | ||
} // namespace clang | ||
|
||
#endif // CATA_TOOLS_CLANG_TIDY_XYCHECK_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// RUN: %check_clang_tidy %s cata-xy %t -- -plugins=%cata_plugin -- | ||
|
||
struct A0 { | ||
// CHECK-MESSAGES: warning: 'A0' defines fields 'x' and 'y'. Consider combining into a single point field. [cata-xy] | ||
int x; | ||
int y; | ||
}; | ||
|
||
struct A1 { | ||
// CHECK-MESSAGES: warning: 'A1' defines fields 'foox' and 'fooy'. Consider combining into a single point field. [cata-xy] | ||
int foox; | ||
int fooy; | ||
}; | ||
|
||
struct A2 { | ||
int foox; | ||
int bary; | ||
}; | ||
|
||
struct A3 { | ||
// CHECK-MESSAGES: warning: 'A3' defines fields 'foox' and 'fooy'. Consider combining into a single point field. [cata-xy] | ||
int foox; | ||
int bary; | ||
int fooy; | ||
}; | ||
|
||
struct A4 { | ||
// CHECK-MESSAGES: warning: 'A4' defines fields 'barx' and 'bary'. Consider combining into a single point field. [cata-xy] | ||
// CHECK-MESSAGES: warning: 'A4' defines fields 'foox' and 'fooy'. Consider combining into a single point field. [cata-xy] | ||
int foox; | ||
int fooy; | ||
int barx; | ||
int bary; | ||
}; | ||
|
||
struct B { | ||
// CHECK-MESSAGES: warning: 'B' defines fields 'x', 'y', and 'z'. Consider combining into a single tripoint field. [cata-xy] | ||
int x; | ||
int y; | ||
int z; | ||
}; | ||
|
||
template<int> | ||
struct C { | ||
// CHECK-MESSAGES: warning: 'C' defines fields 'x' and 'y'. Consider combining into a single point field. [cata-xy] | ||
int x; | ||
int y; | ||
}; | ||
|
||
C<0> c0; | ||
C<1> c1; | ||
|
||
struct D { | ||
// Verify that there are no warnings for non-int types | ||
float x; | ||
float y; | ||
}; |