forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'llvm/release/9.x' into rustc/9.0-2019-0…
…7-12
- Loading branch information
Showing
1,288 changed files
with
48,086 additions
and
13,809 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
172 changes: 172 additions & 0 deletions
172
clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp
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,172 @@ | ||
//===--- ConvertMemberFunctionsToStatic.cpp - clang-tidy ------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "ConvertMemberFunctionsToStatic.h" | ||
#include "clang/AST/ASTContext.h" | ||
#include "clang/AST/DeclCXX.h" | ||
#include "clang/AST/RecursiveASTVisitor.h" | ||
#include "clang/ASTMatchers/ASTMatchFinder.h" | ||
#include "clang/Basic/SourceLocation.h" | ||
|
||
using namespace clang::ast_matchers; | ||
|
||
namespace clang { | ||
namespace tidy { | ||
namespace readability { | ||
|
||
AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); } | ||
|
||
AST_MATCHER(CXXMethodDecl, hasTrivialBody) { return Node.hasTrivialBody(); } | ||
|
||
AST_MATCHER(CXXMethodDecl, isOverloadedOperator) { | ||
return Node.isOverloadedOperator(); | ||
} | ||
|
||
AST_MATCHER(CXXRecordDecl, hasAnyDependentBases) { | ||
return Node.hasAnyDependentBases(); | ||
} | ||
|
||
AST_MATCHER(CXXMethodDecl, isTemplate) { | ||
return Node.getTemplatedKind() != FunctionDecl::TK_NonTemplate; | ||
} | ||
|
||
AST_MATCHER(CXXMethodDecl, isDependentContext) { | ||
return Node.isDependentContext(); | ||
} | ||
|
||
AST_MATCHER(CXXMethodDecl, isInsideMacroDefinition) { | ||
const ASTContext &Ctxt = Finder->getASTContext(); | ||
return clang::Lexer::makeFileCharRange( | ||
clang::CharSourceRange::getCharRange( | ||
Node.getTypeSourceInfo()->getTypeLoc().getSourceRange()), | ||
Ctxt.getSourceManager(), Ctxt.getLangOpts()) | ||
.isInvalid(); | ||
} | ||
|
||
AST_MATCHER_P(CXXMethodDecl, hasCanonicalDecl, | ||
ast_matchers::internal::Matcher<CXXMethodDecl>, InnerMatcher) { | ||
return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder); | ||
} | ||
|
||
AST_MATCHER(CXXMethodDecl, usesThis) { | ||
class FindUsageOfThis : public RecursiveASTVisitor<FindUsageOfThis> { | ||
public: | ||
bool Used = false; | ||
|
||
bool VisitCXXThisExpr(const CXXThisExpr *E) { | ||
Used = true; | ||
return false; // Stop traversal. | ||
} | ||
} UsageOfThis; | ||
|
||
// TraverseStmt does not modify its argument. | ||
UsageOfThis.TraverseStmt(const_cast<Stmt *>(Node.getBody())); | ||
|
||
return UsageOfThis.Used; | ||
} | ||
|
||
void ConvertMemberFunctionsToStatic::registerMatchers(MatchFinder *Finder) { | ||
Finder->addMatcher( | ||
cxxMethodDecl( | ||
isDefinition(), isUserProvided(), | ||
unless(anyOf( | ||
isExpansionInSystemHeader(), isVirtual(), isStatic(), | ||
hasTrivialBody(), isOverloadedOperator(), cxxConstructorDecl(), | ||
cxxDestructorDecl(), cxxConversionDecl(), isTemplate(), | ||
isDependentContext(), | ||
ofClass(anyOf( | ||
isLambda(), | ||
hasAnyDependentBases()) // Method might become virtual | ||
// depending on template base class. | ||
), | ||
isInsideMacroDefinition(), | ||
hasCanonicalDecl(isInsideMacroDefinition()), usesThis()))) | ||
.bind("x"), | ||
this); | ||
} | ||
|
||
/// \brief Obtain the original source code text from a SourceRange. | ||
static StringRef getStringFromRange(SourceManager &SourceMgr, | ||
const LangOptions &LangOpts, | ||
SourceRange Range) { | ||
if (SourceMgr.getFileID(Range.getBegin()) != | ||
SourceMgr.getFileID(Range.getEnd())) | ||
return {}; | ||
|
||
return Lexer::getSourceText(CharSourceRange(Range, true), SourceMgr, | ||
LangOpts); | ||
} | ||
|
||
static SourceRange getLocationOfConst(const TypeSourceInfo *TSI, | ||
SourceManager &SourceMgr, | ||
const LangOptions &LangOpts) { | ||
assert(TSI); | ||
const auto FTL = TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>(); | ||
assert(FTL); | ||
|
||
SourceRange Range{FTL.getRParenLoc().getLocWithOffset(1), | ||
FTL.getLocalRangeEnd()}; | ||
// Inside Range, there might be other keywords and trailing return types. | ||
// Find the exact position of "const". | ||
StringRef Text = getStringFromRange(SourceMgr, LangOpts, Range); | ||
size_t Offset = Text.find("const"); | ||
if (Offset == StringRef::npos) | ||
return {}; | ||
|
||
SourceLocation Start = Range.getBegin().getLocWithOffset(Offset); | ||
return {Start, Start.getLocWithOffset(strlen("const") - 1)}; | ||
} | ||
|
||
void ConvertMemberFunctionsToStatic::check( | ||
const MatchFinder::MatchResult &Result) { | ||
const auto *Definition = Result.Nodes.getNodeAs<CXXMethodDecl>("x"); | ||
|
||
// TODO: For out-of-line declarations, don't modify the source if the header | ||
// is excluded by the -header-filter option. | ||
DiagnosticBuilder Diag = | ||
diag(Definition->getLocation(), "method %0 can be made static") | ||
<< Definition; | ||
|
||
// TODO: Would need to remove those in a fix-it. | ||
if (Definition->getMethodQualifiers().hasVolatile() || | ||
Definition->getMethodQualifiers().hasRestrict() || | ||
Definition->getRefQualifier() != RQ_None) | ||
return; | ||
|
||
const CXXMethodDecl *Declaration = Definition->getCanonicalDecl(); | ||
|
||
if (Definition->isConst()) { | ||
// Make sure that we either remove 'const' on both declaration and | ||
// definition or emit no fix-it at all. | ||
SourceRange DefConst = getLocationOfConst(Definition->getTypeSourceInfo(), | ||
*Result.SourceManager, | ||
Result.Context->getLangOpts()); | ||
|
||
if (DefConst.isInvalid()) | ||
return; | ||
|
||
if (Declaration != Definition) { | ||
SourceRange DeclConst = getLocationOfConst( | ||
Declaration->getTypeSourceInfo(), *Result.SourceManager, | ||
Result.Context->getLangOpts()); | ||
|
||
if (DeclConst.isInvalid()) | ||
return; | ||
Diag << FixItHint::CreateRemoval(DeclConst); | ||
} | ||
|
||
// Remove existing 'const' from both declaration and definition. | ||
Diag << FixItHint::CreateRemoval(DefConst); | ||
} | ||
Diag << FixItHint::CreateInsertion(Declaration->getBeginLoc(), "static "); | ||
} | ||
|
||
} // namespace readability | ||
} // namespace tidy | ||
} // namespace clang |
37 changes: 37 additions & 0 deletions
37
clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.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,37 @@ | ||
//===--- ConvertMemberFunctionsToStatic.h - clang-tidy ----------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMFUNCTOSTATIC_H | ||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMFUNCTOSTATIC_H | ||
|
||
#include "../ClangTidy.h" | ||
|
||
namespace clang { | ||
namespace tidy { | ||
namespace readability { | ||
|
||
/// This check finds C++ class methods than can be made static | ||
/// because they don't use the 'this' pointer. | ||
/// | ||
/// For the user-facing documentation see: | ||
/// http://clang.llvm.org/extra/clang-tidy/checks/ | ||
/// readability-convert-member-functions-to-static.html | ||
class ConvertMemberFunctionsToStatic : public ClangTidyCheck { | ||
public: | ||
ConvertMemberFunctionsToStatic(StringRef Name, ClangTidyContext *Context) | ||
: ClangTidyCheck(Name, Context) {} | ||
void registerMatchers(ast_matchers::MatchFinder *Finder) override; | ||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override; | ||
}; | ||
|
||
} // namespace readability | ||
} // namespace tidy | ||
} // namespace clang | ||
|
||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMFUNCTOSTATIC_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
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
Oops, something went wrong.