Index: include/clang/Analysis/CloneDetection.h =================================================================== --- include/clang/Analysis/CloneDetection.h +++ include/clang/Analysis/CloneDetection.h @@ -301,14 +301,19 @@ MinComplexityConstraint(unsigned MinComplexity) : MinComplexity(MinComplexity) {} - size_t calculateStmtComplexity(const StmtSequence &Seq, + /// Calculates the complexity of the given StmtSequence. + /// \param Limit The limit of complexity we probe for. After reaching + /// this limit during calculation, this method is exiting + /// early to improve performance and returns this limit. + size_t calculateStmtComplexity(const StmtSequence &Seq, std::size_t Limit, const std::string &ParentMacroStack = ""); void constrain(std::vector &CloneGroups) { CloneConstraint::filterGroups( CloneGroups, [this](const CloneDetector::CloneGroup &A) { if (!A.empty()) - return calculateStmtComplexity(A.front()) < MinComplexity; + return calculateStmtComplexity(A.front(), MinComplexity) < + MinComplexity; else return false; }); Index: lib/Analysis/CloneDetection.cpp =================================================================== --- lib/Analysis/CloneDetection.cpp +++ lib/Analysis/CloneDetection.cpp @@ -562,7 +562,8 @@ } size_t MinComplexityConstraint::calculateStmtComplexity( - const StmtSequence &Seq, const std::string &ParentMacroStack) { + const StmtSequence &Seq, std::size_t Limit, + const std::string &ParentMacroStack) { if (Seq.empty()) return 0; @@ -571,8 +572,7 @@ ASTContext &Context = Seq.getASTContext(); // Look up what macros expanded into the current statement. - std::string StartMacroStack = getMacroStack(Seq.getStartLoc(), Context); - std::string EndMacroStack = getMacroStack(Seq.getEndLoc(), Context); + std::string MacroStack = getMacroStack(Seq.getStartLoc(), Context); // First, check if ParentMacroStack is not empty which means we are currently // dealing with a parent statement which was expanded from a macro. @@ -582,8 +582,7 @@ // macro expansion will only increase the total complexity by one. // Note: This is not the final complexity of this statement as we still // add the complexity of the child statements to the complexity value. - if (!ParentMacroStack.empty() && (StartMacroStack == ParentMacroStack && - EndMacroStack == ParentMacroStack)) { + if (!ParentMacroStack.empty() && MacroStack == ParentMacroStack) { Complexity = 0; } @@ -592,12 +591,16 @@ if (Seq.holdsSequence()) { for (const Stmt *S : Seq) { Complexity += calculateStmtComplexity( - StmtSequence(S, Seq.getContainingDecl()), StartMacroStack); + StmtSequence(S, Seq.getContainingDecl()), Limit, MacroStack); + if (Complexity >= Limit) + return Limit; } } else { for (const Stmt *S : Seq.front()->children()) { Complexity += calculateStmtComplexity( - StmtSequence(S, Seq.getContainingDecl()), StartMacroStack); + StmtSequence(S, Seq.getContainingDecl()), Limit, MacroStack); + if (Complexity >= Limit) + return Limit; } } return Complexity;