29 :
public Checker<check::ASTCodeBody, check::EndOfTranslationUnit> {
33 bool ReportNormalClones =
false;
34 StringRef IgnoredFilesPattern;
37 mutable CloneDetector Detector;
38 const BugType BT_Exact{
this,
"Exact code clone",
"Code clone"};
39 const BugType BT_Suspicious{
this,
"Suspicious code clone",
"Code clone"};
42 void checkASTCodeBody(
const Decl *D, AnalysisManager &Mgr,
43 BugReporter &BR)
const;
45 void checkEndOfTranslationUnit(
const TranslationUnitDecl *TU,
46 AnalysisManager &Mgr, BugReporter &BR)
const;
49 void reportClones(BugReporter &BR, AnalysisManager &Mgr,
50 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const;
54 void reportSuspiciousClones(
55 BugReporter &BR, AnalysisManager &Mgr,
56 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const;
67void CloneChecker::checkEndOfTranslationUnit(
const TranslationUnitDecl *TU,
69 BugReporter &BR)
const {
76 std::vector<CloneDetector::CloneGroup> AllCloneGroups;
79 AllCloneGroups, FilenamePatternConstraint(IgnoredFilesPattern),
80 RecursiveCloneTypeIIHashConstraint(), MinGroupSizeConstraint(2),
81 MinComplexityConstraint(MinComplexity),
82 RecursiveCloneTypeIIVerifyConstraint(), OnlyLargestCloneConstraint());
84 reportSuspiciousClones(BR, Mgr, AllCloneGroups);
88 if (!ReportNormalClones)
94 MatchingVariablePatternConstraint(),
95 MinGroupSizeConstraint(2));
97 reportClones(BR, Mgr, AllCloneGroups);
108void CloneChecker::reportClones(
109 BugReporter &BR, AnalysisManager &Mgr,
110 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const {
114 auto R = std::make_unique<BasicBugReport>(
116 R->addRange(
Group.front().getSourceRange());
118 for (
unsigned i = 1; i <
Group.size(); ++i)
119 R->addNote(
"Similar code here",
makeLocation(Group[i], Mgr),
125void CloneChecker::reportSuspiciousClones(
126 BugReporter &BR, AnalysisManager &Mgr,
127 std::vector<CloneDetector::CloneGroup> &CloneGroups)
const {
128 std::vector<VariablePattern::SuspiciousClonePair> Pairs;
131 for (
unsigned i = 0; i <
Group.size(); ++i) {
132 VariablePattern PatternA(Group[i]);
134 for (
unsigned j = i + 1; j <
Group.size(); ++j) {
135 VariablePattern PatternB(Group[j]);
137 VariablePattern::SuspiciousClonePair ClonePair;
146 if (PatternA.countPatternDifferences(PatternB, &ClonePair) == 1) {
147 Pairs.push_back(ClonePair);
156 AnalysisDeclContext *ADC =
159 for (VariablePattern::SuspiciousClonePair &Pair : Pairs) {
165 auto R = std::make_unique<BasicBugReport>(
167 "Potential copy-paste error; did you really mean to use '" +
168 Pair.FirstCloneInfo.Variable->getNameAsString() +
"' here?",
171 R->addRange(Pair.FirstCloneInfo.Mention->getSourceRange());
173 R->addNote(
"Similar code using '" +
174 Pair.SecondCloneInfo.Variable->getNameAsString() +
"' here",
177 Pair.SecondCloneInfo.Mention->getSourceRange());
187void ento::registerCloneChecker(CheckerManager &Mgr) {
191 Checker,
"MinimumCloneComplexity");
193 if (Checker->MinComplexity < 0)
195 Checker,
"MinimumCloneComplexity",
"a non-negative value");
198 Checker,
"ReportNormalClones");
204bool ento::shouldRegisterCloneChecker(
const CheckerManager &mgr) {
Defines the Diagnostic-related interfaces.
static PathDiagnosticLocation makeLocation(const StmtSequence &S, AnalysisManager &Mgr)
This file defines classes for searching and analyzing source code clones.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
TranslationUnitDecl * getTranslationUnitDecl() const
int getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName, bool SearchInParents=false) const
Interprets an option's string value as a boolean.
StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName, bool SearchInParents=false) const
Query an option's string value.
void findClones(std::vector< CloneGroup > &Result, Ts... ConstraintList)
Searches for clones in all previously passed statements.
static void constrainClones(std::vector< CloneGroup > &CloneGroups, T C)
Constrains the given list of clone groups with the given constraint.
void analyzeCodeBody(const Decl *D)
Generates and stores search data for all statements in the body of the given Decl.
llvm::SmallVector< StmtSequence, 8 > CloneGroup
A collection of StmtSequences that share an arbitrary property.
Decl - This represents one declaration (or definition), e.g.
Identifies a list of statements.
const Stmt * front() const
Returns the first statement in this sequence.
ASTContext & getASTContext() override
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
BugReporter is a utility class for generating PathDiagnostics for analysis.
ASTContext & getContext()
virtual void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
const AnalyzerOptions & getAnalyzerOptions() const
CHECKER * registerChecker(AT &&...Args)
Register a single-part checker (derived from Checker): construct its singleton instance,...
void reportInvalidCheckerOptionValue(const CheckerFrontend *Checker, StringRef OptionName, StringRef ExpectedValueDesc) const
Emits an error through a DiagnosticsEngine about an invalid user supplied checker option value.
Simple checker classes that implement one frontend (i.e.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
The JSON file list parser is used to communicate input to InstallAPI.