forked from OSchip/llvm-project
[clang-tidy] Refactor IncludeInserter
Simplified how `IncludeInserter` is used in Checks by abstracting away the SourceManager and PPCallbacks inside the method `registerPreprocessor`. Changed checks that use `IncludeInserter` to no longer use a `std::unique_ptr`, instead the IncludeInserter is just a member of the class thats initialized with an `IncludeStyle`. Saving an unnecessary allocation. This results in the removal of the field `IncludeSorter::IncludeStyle` from the checks, as its wrapped in the `IncludeInserter`. No longer need to create an instance of the `IncludeInserter` in the registerPPCallbacks, now that method only needs to contain: ``` Inserter.registerPreprocessor(PP); ``` Also added a helper method to `IncludeInserter` called `createMainFileInclusionInsertion`, purely sugar but does better express intentions. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D83680
This commit is contained in:
parent
47a0254229
commit
13c9bbc28e
|
@ -26,7 +26,7 @@ StringFindStartswithCheck::StringFindStartswithCheck(StringRef Name,
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
StringLikeClasses(utils::options::parseStringList(
|
StringLikeClasses(utils::options::parseStringList(
|
||||||
Options.get("StringLikeClasses", "::std::basic_string"))),
|
Options.get("StringLikeClasses", "::std::basic_string"))),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)),
|
utils::IncludeSorter::IS_LLVM)),
|
||||||
AbseilStringsMatchHeader(
|
AbseilStringsMatchHeader(
|
||||||
Options.get("AbseilStringsMatchHeader", "absl/strings/match.h")) {}
|
Options.get("AbseilStringsMatchHeader", "absl/strings/match.h")) {}
|
||||||
|
@ -105,23 +105,21 @@ void StringFindStartswithCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
|
||||||
// Create a preprocessor #include FixIt hint (CreateIncludeInsertion checks
|
// Create a preprocessor #include FixIt hint (CreateIncludeInsertion checks
|
||||||
// whether this already exists).
|
// whether this already exists).
|
||||||
Diagnostic << IncludeInserter->CreateIncludeInsertion(
|
Diagnostic << IncludeInserter.createIncludeInsertion(
|
||||||
Source.getFileID(ComparisonExpr->getBeginLoc()), AbseilStringsMatchHeader,
|
Source.getFileID(ComparisonExpr->getBeginLoc()), AbseilStringsMatchHeader,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringFindStartswithCheck::registerPPCallbacks(
|
void StringFindStartswithCheck::registerPPCallbacks(
|
||||||
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
||||||
IncludeInserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
|
IncludeInserter.registerPreprocessor(PP);
|
||||||
IncludeStyle);
|
|
||||||
PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringFindStartswithCheck::storeOptions(
|
void StringFindStartswithCheck::storeOptions(
|
||||||
ClangTidyOptions::OptionMap &Opts) {
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "StringLikeClasses",
|
Options.store(Opts, "StringLikeClasses",
|
||||||
utils::options::serializeStringList(StringLikeClasses));
|
utils::options::serializeStringList(StringLikeClasses));
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
|
||||||
Options.store(Opts, "AbseilStringsMatchHeader", AbseilStringsMatchHeader);
|
Options.store(Opts, "AbseilStringsMatchHeader", AbseilStringsMatchHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,8 @@ public:
|
||||||
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<clang::tidy::utils::IncludeInserter> IncludeInserter;
|
|
||||||
const std::vector<std::string> StringLikeClasses;
|
const std::vector<std::string> StringLikeClasses;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
utils::IncludeInserter IncludeInserter;
|
||||||
const std::string AbseilStringsMatchHeader;
|
const std::string AbseilStringsMatchHeader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,12 +26,12 @@ AST_MATCHER(VarDecl, isLocalVarDecl) { return Node.isLocalVarDecl(); }
|
||||||
InitVariablesCheck::InitVariablesCheck(StringRef Name,
|
InitVariablesCheck::InitVariablesCheck(StringRef Name,
|
||||||
ClangTidyContext *Context)
|
ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)),
|
utils::IncludeSorter::IS_LLVM)),
|
||||||
MathHeader(Options.get("MathHeader", "math.h")) {}
|
MathHeader(Options.get("MathHeader", "math.h")) {}
|
||||||
|
|
||||||
void InitVariablesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
void InitVariablesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
|
||||||
Options.store(Opts, "MathHeader", MathHeader);
|
Options.store(Opts, "MathHeader", MathHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,9 +51,7 @@ void InitVariablesCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
void InitVariablesCheck::registerPPCallbacks(const SourceManager &SM,
|
void InitVariablesCheck::registerPPCallbacks(const SourceManager &SM,
|
||||||
Preprocessor *PP,
|
Preprocessor *PP,
|
||||||
Preprocessor *ModuleExpanderPP) {
|
Preprocessor *ModuleExpanderPP) {
|
||||||
IncludeInserter =
|
IncludeInserter.registerPreprocessor(PP);
|
||||||
std::make_unique<utils::IncludeInserter>(SM, getLangOpts(), IncludeStyle);
|
|
||||||
PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitVariablesCheck::check(const MatchFinder::MatchResult &Result) {
|
void InitVariablesCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
@ -104,7 +102,7 @@ void InitVariablesCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
MatchedDecl->getName().size()),
|
MatchedDecl->getName().size()),
|
||||||
InitializationString);
|
InitializationString);
|
||||||
if (AddMathInclude) {
|
if (AddMathInclude) {
|
||||||
Diagnostic << IncludeInserter->CreateIncludeInsertion(
|
Diagnostic << IncludeInserter.createIncludeInsertion(
|
||||||
Source.getFileID(MatchedDecl->getBeginLoc()), MathHeader, false);
|
Source.getFileID(MatchedDecl->getBeginLoc()), MathHeader, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,7 @@ public:
|
||||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<clang::tidy::utils::IncludeInserter> IncludeInserter;
|
utils::IncludeInserter IncludeInserter;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
|
||||||
const std::string MathHeader;
|
const std::string MathHeader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,20 +21,18 @@ namespace cppcoreguidelines {
|
||||||
ProBoundsConstantArrayIndexCheck::ProBoundsConstantArrayIndexCheck(
|
ProBoundsConstantArrayIndexCheck::ProBoundsConstantArrayIndexCheck(
|
||||||
StringRef Name, ClangTidyContext *Context)
|
StringRef Name, ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context), GslHeader(Options.get("GslHeader", "")),
|
: ClangTidyCheck(Name, Context), GslHeader(Options.get("GslHeader", "")),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
Inserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)) {}
|
utils::IncludeSorter::IS_LLVM)) {}
|
||||||
|
|
||||||
void ProBoundsConstantArrayIndexCheck::storeOptions(
|
void ProBoundsConstantArrayIndexCheck::storeOptions(
|
||||||
ClangTidyOptions::OptionMap &Opts) {
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "GslHeader", GslHeader);
|
Options.store(Opts, "GslHeader", GslHeader);
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProBoundsConstantArrayIndexCheck::registerPPCallbacks(
|
void ProBoundsConstantArrayIndexCheck::registerPPCallbacks(
|
||||||
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
||||||
Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
|
Inserter.registerPreprocessor(PP);
|
||||||
IncludeStyle);
|
|
||||||
PP->addPPCallbacks(Inserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) {
|
void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
|
@ -87,8 +85,7 @@ void ProBoundsConstantArrayIndexCheck::check(
|
||||||
IndexRange.getBegin().getLocWithOffset(-1)),
|
IndexRange.getBegin().getLocWithOffset(-1)),
|
||||||
", ")
|
", ")
|
||||||
<< FixItHint::CreateReplacement(Matched->getEndLoc(), ")")
|
<< FixItHint::CreateReplacement(Matched->getEndLoc(), ")")
|
||||||
<< Inserter->CreateIncludeInsertion(
|
<< Inserter.createMainFileIncludeInsertion(GslHeader,
|
||||||
Result.SourceManager->getMainFileID(), GslHeader,
|
|
||||||
/*IsAngled=*/false);
|
/*IsAngled=*/false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -23,8 +23,7 @@ namespace cppcoreguidelines {
|
||||||
/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.html
|
/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.html
|
||||||
class ProBoundsConstantArrayIndexCheck : public ClangTidyCheck {
|
class ProBoundsConstantArrayIndexCheck : public ClangTidyCheck {
|
||||||
const std::string GslHeader;
|
const std::string GslHeader;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
utils::IncludeInserter Inserter;
|
||||||
std::unique_ptr<utils::IncludeInserter> Inserter;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ProBoundsConstantArrayIndexCheck(StringRef Name, ClangTidyContext *Context);
|
ProBoundsConstantArrayIndexCheck(StringRef Name, ClangTidyContext *Context);
|
||||||
|
|
|
@ -44,7 +44,7 @@ const char MakeSmartPtrCheck::PointerType[] = "pointerType";
|
||||||
MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
|
MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
|
||||||
StringRef MakeSmartPtrFunctionName)
|
StringRef MakeSmartPtrFunctionName)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
Inserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)),
|
utils::IncludeSorter::IS_LLVM)),
|
||||||
MakeSmartPtrFunctionHeader(
|
MakeSmartPtrFunctionHeader(
|
||||||
Options.get("MakeSmartPtrFunctionHeader", StdMemoryHeader)),
|
Options.get("MakeSmartPtrFunctionHeader", StdMemoryHeader)),
|
||||||
|
@ -53,7 +53,7 @@ MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
|
||||||
IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {}
|
IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {}
|
||||||
|
|
||||||
void MakeSmartPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
void MakeSmartPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
|
||||||
Options.store(Opts, "MakeSmartPtrFunctionHeader", MakeSmartPtrFunctionHeader);
|
Options.store(Opts, "MakeSmartPtrFunctionHeader", MakeSmartPtrFunctionHeader);
|
||||||
Options.store(Opts, "MakeSmartPtrFunction", MakeSmartPtrFunctionName);
|
Options.store(Opts, "MakeSmartPtrFunction", MakeSmartPtrFunctionName);
|
||||||
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
|
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
|
||||||
|
@ -67,9 +67,7 @@ bool MakeSmartPtrCheck::isLanguageVersionSupported(
|
||||||
void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager &SM,
|
void MakeSmartPtrCheck::registerPPCallbacks(const SourceManager &SM,
|
||||||
Preprocessor *PP,
|
Preprocessor *PP,
|
||||||
Preprocessor *ModuleExpanderPP) {
|
Preprocessor *ModuleExpanderPP) {
|
||||||
Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
|
Inserter.registerPreprocessor(PP);
|
||||||
IncludeStyle);
|
|
||||||
PP->addPPCallbacks(Inserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
||||||
|
@ -432,7 +430,7 @@ void MakeSmartPtrCheck::insertHeader(DiagnosticBuilder &Diag, FileID FD) {
|
||||||
if (MakeSmartPtrFunctionHeader.empty()) {
|
if (MakeSmartPtrFunctionHeader.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Diag << Inserter->CreateIncludeInsertion(
|
Diag << Inserter.createIncludeInsertion(
|
||||||
FD, MakeSmartPtrFunctionHeader,
|
FD, MakeSmartPtrFunctionHeader,
|
||||||
/*IsAngled=*/MakeSmartPtrFunctionHeader == StdMemoryHeader);
|
/*IsAngled=*/MakeSmartPtrFunctionHeader == StdMemoryHeader);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,7 @@ protected:
|
||||||
static const char PointerType[];
|
static const char PointerType[];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<utils::IncludeInserter> Inserter;
|
utils::IncludeInserter Inserter;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
|
||||||
const std::string MakeSmartPtrFunctionHeader;
|
const std::string MakeSmartPtrFunctionHeader;
|
||||||
const std::string MakeSmartPtrFunctionName;
|
const std::string MakeSmartPtrFunctionName;
|
||||||
const bool IgnoreMacros;
|
const bool IgnoreMacros;
|
||||||
|
|
|
@ -120,12 +120,12 @@ collectParamDecls(const CXXConstructorDecl *Ctor,
|
||||||
|
|
||||||
PassByValueCheck::PassByValueCheck(StringRef Name, ClangTidyContext *Context)
|
PassByValueCheck::PassByValueCheck(StringRef Name, ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
Inserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)),
|
utils::IncludeSorter::IS_LLVM)),
|
||||||
ValuesOnly(Options.get("ValuesOnly", false)) {}
|
ValuesOnly(Options.get("ValuesOnly", false)) {}
|
||||||
|
|
||||||
void PassByValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
void PassByValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
|
||||||
Options.store(Opts, "ValuesOnly", ValuesOnly);
|
Options.store(Opts, "ValuesOnly", ValuesOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,9 +167,7 @@ void PassByValueCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
void PassByValueCheck::registerPPCallbacks(const SourceManager &SM,
|
void PassByValueCheck::registerPPCallbacks(const SourceManager &SM,
|
||||||
Preprocessor *PP,
|
Preprocessor *PP,
|
||||||
Preprocessor *ModuleExpanderPP) {
|
Preprocessor *ModuleExpanderPP) {
|
||||||
Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
|
Inserter.registerPreprocessor(PP);
|
||||||
IncludeStyle);
|
|
||||||
PP->addPPCallbacks(Inserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PassByValueCheck::check(const MatchFinder::MatchResult &Result) {
|
void PassByValueCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
@ -216,7 +214,7 @@ void PassByValueCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
Diag << FixItHint::CreateInsertion(Initializer->getRParenLoc(), ")")
|
Diag << FixItHint::CreateInsertion(Initializer->getRParenLoc(), ")")
|
||||||
<< FixItHint::CreateInsertion(
|
<< FixItHint::CreateInsertion(
|
||||||
Initializer->getLParenLoc().getLocWithOffset(1), "std::move(")
|
Initializer->getLParenLoc().getLocWithOffset(1), "std::move(")
|
||||||
<< Inserter->CreateIncludeInsertion(
|
<< Inserter.createIncludeInsertion(
|
||||||
Result.SourceManager->getFileID(Initializer->getSourceLocation()),
|
Result.SourceManager->getFileID(Initializer->getSourceLocation()),
|
||||||
"utility",
|
"utility",
|
||||||
/*IsAngled=*/true);
|
/*IsAngled=*/true);
|
||||||
|
|
|
@ -31,8 +31,7 @@ public:
|
||||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<utils::IncludeInserter> Inserter;
|
utils::IncludeInserter Inserter;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
|
||||||
const bool ValuesOnly;
|
const bool ValuesOnly;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -74,11 +74,11 @@ AST_MATCHER(Decl, isFromStdNamespace) {
|
||||||
ReplaceAutoPtrCheck::ReplaceAutoPtrCheck(StringRef Name,
|
ReplaceAutoPtrCheck::ReplaceAutoPtrCheck(StringRef Name,
|
||||||
ClangTidyContext *Context)
|
ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
Inserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)) {}
|
utils::IncludeSorter::IS_LLVM)) {}
|
||||||
|
|
||||||
void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
|
void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
|
@ -131,9 +131,7 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
void ReplaceAutoPtrCheck::registerPPCallbacks(const SourceManager &SM,
|
void ReplaceAutoPtrCheck::registerPPCallbacks(const SourceManager &SM,
|
||||||
Preprocessor *PP,
|
Preprocessor *PP,
|
||||||
Preprocessor *ModuleExpanderPP) {
|
Preprocessor *ModuleExpanderPP) {
|
||||||
Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
|
Inserter.registerPreprocessor(PP);
|
||||||
IncludeStyle);
|
|
||||||
PP->addPPCallbacks(Inserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
|
void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
@ -146,11 +144,10 @@ void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
if (Range.isInvalid())
|
if (Range.isInvalid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto Diag =
|
auto Diag = diag(Range.getBegin(), "use std::move to transfer ownership")
|
||||||
diag(Range.getBegin(), "use std::move to transfer ownership")
|
|
||||||
<< FixItHint::CreateInsertion(Range.getBegin(), "std::move(")
|
<< FixItHint::CreateInsertion(Range.getBegin(), "std::move(")
|
||||||
<< FixItHint::CreateInsertion(Range.getEnd(), ")")
|
<< FixItHint::CreateInsertion(Range.getEnd(), ")")
|
||||||
<< Inserter->CreateIncludeInsertion(SM.getMainFileID(), "utility",
|
<< Inserter.createMainFileIncludeInsertion("utility",
|
||||||
/*IsAngled=*/true);
|
/*IsAngled=*/true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -53,8 +53,7 @@ public:
|
||||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<utils::IncludeInserter> Inserter;
|
utils::IncludeInserter Inserter;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace modernize
|
} // namespace modernize
|
||||||
|
|
|
@ -23,8 +23,9 @@ namespace modernize {
|
||||||
ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name,
|
ReplaceRandomShuffleCheck::ReplaceRandomShuffleCheck(StringRef Name,
|
||||||
ClangTidyContext *Context)
|
ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)) {}
|
utils::IncludeSorter::IS_LLVM)) {
|
||||||
|
}
|
||||||
|
|
||||||
void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) {
|
void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
const auto Begin = hasArgument(0, expr());
|
const auto Begin = hasArgument(0, expr());
|
||||||
|
@ -44,14 +45,12 @@ void ReplaceRandomShuffleCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
|
|
||||||
void ReplaceRandomShuffleCheck::registerPPCallbacks(
|
void ReplaceRandomShuffleCheck::registerPPCallbacks(
|
||||||
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
||||||
IncludeInserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
|
IncludeInserter.registerPreprocessor(PP);
|
||||||
IncludeStyle);
|
|
||||||
PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplaceRandomShuffleCheck::storeOptions(
|
void ReplaceRandomShuffleCheck::storeOptions(
|
||||||
ClangTidyOptions::OptionMap &Opts) {
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) {
|
void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
@ -92,7 +91,7 @@ void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
|
||||||
Diag << FixItHint::CreateRemoval(MatchedDecl->getSourceRange());
|
Diag << FixItHint::CreateRemoval(MatchedDecl->getSourceRange());
|
||||||
Diag << FixItHint::CreateInsertion(MatchedDecl->getBeginLoc(), NewName);
|
Diag << FixItHint::CreateInsertion(MatchedDecl->getBeginLoc(), NewName);
|
||||||
Diag << IncludeInserter->CreateIncludeInsertion(
|
Diag << IncludeInserter.createIncludeInsertion(
|
||||||
Result.Context->getSourceManager().getFileID(
|
Result.Context->getSourceManager().getFileID(
|
||||||
MatchedCallExpr->getBeginLoc()),
|
MatchedCallExpr->getBeginLoc()),
|
||||||
"random", /*IsAngled=*/true);
|
"random", /*IsAngled=*/true);
|
||||||
|
|
|
@ -34,8 +34,7 @@ public:
|
||||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<utils::IncludeInserter> IncludeInserter;
|
utils::IncludeInserter IncludeInserter;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace modernize
|
} // namespace modernize
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace performance {
|
||||||
MoveConstructorInitCheck::MoveConstructorInitCheck(StringRef Name,
|
MoveConstructorInitCheck::MoveConstructorInitCheck(StringRef Name,
|
||||||
ClangTidyContext *Context)
|
ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
Inserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)) {}
|
utils::IncludeSorter::IS_LLVM)) {}
|
||||||
|
|
||||||
void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) {
|
void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
|
@ -90,13 +90,11 @@ void MoveConstructorInitCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
|
||||||
void MoveConstructorInitCheck::registerPPCallbacks(
|
void MoveConstructorInitCheck::registerPPCallbacks(
|
||||||
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
||||||
Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
|
Inserter.registerPreprocessor(PP);
|
||||||
IncludeStyle);
|
|
||||||
PP->addPPCallbacks(Inserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveConstructorInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
void MoveConstructorInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace performance
|
} // namespace performance
|
||||||
|
|
|
@ -36,8 +36,7 @@ public:
|
||||||
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<utils::IncludeInserter> Inserter;
|
utils::IncludeInserter Inserter;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace performance
|
} // namespace performance
|
||||||
|
|
|
@ -31,19 +31,18 @@ AST_MATCHER_P(Type, isBuiltinType, BuiltinType::Kind, Kind) {
|
||||||
TypePromotionInMathFnCheck::TypePromotionInMathFnCheck(
|
TypePromotionInMathFnCheck::TypePromotionInMathFnCheck(
|
||||||
StringRef Name, ClangTidyContext *Context)
|
StringRef Name, ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)) {}
|
utils::IncludeSorter::IS_LLVM)) {
|
||||||
|
}
|
||||||
|
|
||||||
void TypePromotionInMathFnCheck::registerPPCallbacks(
|
void TypePromotionInMathFnCheck::registerPPCallbacks(
|
||||||
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
||||||
IncludeInserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
|
IncludeInserter.registerPreprocessor(PP);
|
||||||
IncludeStyle);
|
|
||||||
PP->addPPCallbacks(IncludeInserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypePromotionInMathFnCheck::storeOptions(
|
void TypePromotionInMathFnCheck::storeOptions(
|
||||||
ClangTidyOptions::OptionMap &Opts) {
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypePromotionInMathFnCheck::registerMatchers(MatchFinder *Finder) {
|
void TypePromotionInMathFnCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
|
@ -191,7 +190,7 @@ void TypePromotionInMathFnCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
// <math.h>, because the functions we're suggesting moving away from are all
|
// <math.h>, because the functions we're suggesting moving away from are all
|
||||||
// declared in <math.h>.
|
// declared in <math.h>.
|
||||||
if (FnInCmath)
|
if (FnInCmath)
|
||||||
Diag << IncludeInserter->CreateIncludeInsertion(
|
Diag << IncludeInserter.createIncludeInsertion(
|
||||||
Result.Context->getSourceManager().getFileID(Call->getBeginLoc()),
|
Result.Context->getSourceManager().getFileID(Call->getBeginLoc()),
|
||||||
"cmath", /*IsAngled=*/true);
|
"cmath", /*IsAngled=*/true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,7 @@ public:
|
||||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<utils::IncludeInserter> IncludeInserter;
|
utils::IncludeInserter IncludeInserter;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace performance
|
} // namespace performance
|
||||||
|
|
|
@ -68,7 +68,7 @@ bool isExplicitTemplateSpecialization(const FunctionDecl &Function) {
|
||||||
UnnecessaryValueParamCheck::UnnecessaryValueParamCheck(
|
UnnecessaryValueParamCheck::UnnecessaryValueParamCheck(
|
||||||
StringRef Name, ClangTidyContext *Context)
|
StringRef Name, ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context),
|
: ClangTidyCheck(Name, Context),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
Inserter(Options.getLocalOrGlobal("IncludeStyle",
|
||||||
utils::IncludeSorter::IS_LLVM)),
|
utils::IncludeSorter::IS_LLVM)),
|
||||||
AllowedTypes(
|
AllowedTypes(
|
||||||
utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}
|
utils::options::parseStringList(Options.get("AllowedTypes", ""))) {}
|
||||||
|
@ -173,14 +173,12 @@ void UnnecessaryValueParamCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
|
||||||
void UnnecessaryValueParamCheck::registerPPCallbacks(
|
void UnnecessaryValueParamCheck::registerPPCallbacks(
|
||||||
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
||||||
Inserter = std::make_unique<utils::IncludeInserter>(SM, getLangOpts(),
|
Inserter.registerPreprocessor(PP);
|
||||||
IncludeStyle);
|
|
||||||
PP->addPPCallbacks(Inserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnnecessaryValueParamCheck::storeOptions(
|
void UnnecessaryValueParamCheck::storeOptions(
|
||||||
ClangTidyOptions::OptionMap &Opts) {
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
|
||||||
Options.store(Opts, "AllowedTypes",
|
Options.store(Opts, "AllowedTypes",
|
||||||
utils::options::serializeStringList(AllowedTypes));
|
utils::options::serializeStringList(AllowedTypes));
|
||||||
}
|
}
|
||||||
|
@ -204,7 +202,7 @@ void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Var,
|
||||||
Context.getLangOpts());
|
Context.getLangOpts());
|
||||||
Diag << FixItHint::CreateInsertion(CopyArgument.getBeginLoc(), "std::move(")
|
Diag << FixItHint::CreateInsertion(CopyArgument.getBeginLoc(), "std::move(")
|
||||||
<< FixItHint::CreateInsertion(EndLoc, ")")
|
<< FixItHint::CreateInsertion(EndLoc, ")")
|
||||||
<< Inserter->CreateIncludeInsertion(
|
<< Inserter.createIncludeInsertion(
|
||||||
SM.getFileID(CopyArgument.getBeginLoc()), "utility",
|
SM.getFileID(CopyArgument.getBeginLoc()), "utility",
|
||||||
/*IsAngled=*/true);
|
/*IsAngled=*/true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,7 @@ private:
|
||||||
|
|
||||||
llvm::DenseMap<const FunctionDecl *, FunctionParmMutationAnalyzer>
|
llvm::DenseMap<const FunctionDecl *, FunctionParmMutationAnalyzer>
|
||||||
MutationAnalyzers;
|
MutationAnalyzers;
|
||||||
std::unique_ptr<utils::IncludeInserter> Inserter;
|
utils::IncludeInserter Inserter;
|
||||||
const utils::IncludeSorter::IncludeStyle IncludeStyle;
|
|
||||||
const std::vector<std::string> AllowedTypes;
|
const std::vector<std::string> AllowedTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "IncludeInserter.h"
|
#include "IncludeInserter.h"
|
||||||
|
#include "clang/Lex/PPCallbacks.h"
|
||||||
|
#include "clang/Lex/Preprocessor.h"
|
||||||
#include "clang/Lex/Token.h"
|
#include "clang/Lex/Token.h"
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
@ -26,7 +28,7 @@ public:
|
||||||
StringRef /*SearchPath*/, StringRef /*RelativePath*/,
|
StringRef /*SearchPath*/, StringRef /*RelativePath*/,
|
||||||
const Module * /*ImportedModule*/,
|
const Module * /*ImportedModule*/,
|
||||||
SrcMgr::CharacteristicKind /*FileType*/) override {
|
SrcMgr::CharacteristicKind /*FileType*/) override {
|
||||||
Inserter->AddInclude(FileNameRef, IsAngled, HashLocation,
|
Inserter->addInclude(FileNameRef, IsAngled, HashLocation,
|
||||||
IncludeToken.getEndLoc());
|
IncludeToken.getEndLoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,45 +36,61 @@ private:
|
||||||
IncludeInserter *Inserter;
|
IncludeInserter *Inserter;
|
||||||
};
|
};
|
||||||
|
|
||||||
IncludeInserter::IncludeInserter(const SourceManager &SourceMgr,
|
IncludeInserter::IncludeInserter(IncludeSorter::IncludeStyle Style)
|
||||||
const LangOptions &LangOpts,
|
: Style(Style) {}
|
||||||
IncludeSorter::IncludeStyle Style)
|
|
||||||
: SourceMgr(SourceMgr), Style(Style) {}
|
|
||||||
|
|
||||||
IncludeInserter::~IncludeInserter() {}
|
void IncludeInserter::registerPreprocessor(Preprocessor *PP) {
|
||||||
|
assert(PP && "PP shouldn't be null");
|
||||||
|
SourceMgr = &PP->getSourceManager();
|
||||||
|
|
||||||
std::unique_ptr<PPCallbacks> IncludeInserter::CreatePPCallbacks() {
|
// If this gets registered multiple times, clear the maps
|
||||||
return std::make_unique<IncludeInserterCallback>(this);
|
if (!IncludeSorterByFile.empty())
|
||||||
|
IncludeSorterByFile.clear();
|
||||||
|
if (!InsertedHeaders.empty())
|
||||||
|
InsertedHeaders.clear();
|
||||||
|
PP->addPPCallbacks(std::make_unique<IncludeInserterCallback>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
IncludeSorter &IncludeInserter::getOrCreate(FileID FileID) {
|
IncludeSorter &IncludeInserter::getOrCreate(FileID FileID) {
|
||||||
|
assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call "
|
||||||
|
"registerPreprocessor()?");
|
||||||
// std::unique_ptr is cheap to construct, so force a construction now to save
|
// std::unique_ptr is cheap to construct, so force a construction now to save
|
||||||
// the lookup needed if we were to insert into the map.
|
// the lookup needed if we were to insert into the map.
|
||||||
std::unique_ptr<IncludeSorter> &Entry = IncludeSorterByFile[FileID];
|
std::unique_ptr<IncludeSorter> &Entry = IncludeSorterByFile[FileID];
|
||||||
if (!Entry) {
|
if (!Entry) {
|
||||||
// If it wasn't found, Entry will be default constructed to nullptr.
|
// If it wasn't found, Entry will be default constructed to nullptr.
|
||||||
Entry = std::make_unique<IncludeSorter>(
|
Entry = std::make_unique<IncludeSorter>(
|
||||||
&SourceMgr, FileID,
|
SourceMgr, FileID,
|
||||||
SourceMgr.getFilename(SourceMgr.getLocForStartOfFile(FileID)), Style);
|
SourceMgr->getFilename(SourceMgr->getLocForStartOfFile(FileID)), Style);
|
||||||
}
|
}
|
||||||
return *Entry;
|
return *Entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Optional<FixItHint>
|
llvm::Optional<FixItHint>
|
||||||
IncludeInserter::CreateIncludeInsertion(FileID FileID, StringRef Header,
|
IncludeInserter::createIncludeInsertion(FileID FileID, StringRef Header,
|
||||||
bool IsAngled) {
|
bool IsAngled) {
|
||||||
// We assume the same Header will never be included both angled and not
|
// We assume the same Header will never be included both angled and not
|
||||||
// angled.
|
// angled.
|
||||||
if (!InsertedHeaders[FileID].insert(std::string(Header)).second)
|
if (!InsertedHeaders[FileID].insert(Header).second)
|
||||||
return llvm::None;
|
return llvm::None;
|
||||||
|
|
||||||
return getOrCreate(FileID).CreateIncludeInsertion(Header, IsAngled);
|
return getOrCreate(FileID).CreateIncludeInsertion(Header, IsAngled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IncludeInserter::AddInclude(StringRef FileName, bool IsAngled,
|
llvm::Optional<FixItHint>
|
||||||
|
IncludeInserter::createMainFileIncludeInsertion(StringRef Header,
|
||||||
|
bool IsAngled) {
|
||||||
|
assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call "
|
||||||
|
"registerPreprocessor()?");
|
||||||
|
return createIncludeInsertion(SourceMgr->getMainFileID(), Header, IsAngled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IncludeInserter::addInclude(StringRef FileName, bool IsAngled,
|
||||||
SourceLocation HashLocation,
|
SourceLocation HashLocation,
|
||||||
SourceLocation EndLocation) {
|
SourceLocation EndLocation) {
|
||||||
FileID FileID = SourceMgr.getFileID(HashLocation);
|
assert(SourceMgr && "SourceMgr shouldn't be null; did you remember to call "
|
||||||
|
"registerPreprocessor()?");
|
||||||
|
FileID FileID = SourceMgr->getFileID(HashLocation);
|
||||||
getOrCreate(FileID).AddInclude(FileName, IsAngled, HashLocation, EndLocation);
|
getOrCreate(FileID).AddInclude(FileName, IsAngled, HashLocation, EndLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,11 @@
|
||||||
|
|
||||||
#include "IncludeSorter.h"
|
#include "IncludeSorter.h"
|
||||||
#include "clang/Basic/Diagnostic.h"
|
#include "clang/Basic/Diagnostic.h"
|
||||||
#include "clang/Basic/LangOptions.h"
|
#include "llvm/ADT/StringSet.h"
|
||||||
#include "clang/Basic/SourceManager.h"
|
|
||||||
#include "clang/Lex/PPCallbacks.h"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
class Preprocessor;
|
||||||
namespace tidy {
|
namespace tidy {
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
|
@ -26,16 +24,17 @@ namespace utils {
|
||||||
///
|
///
|
||||||
/// ``IncludeInserter`` can be used in clang-tidy checks in the following way:
|
/// ``IncludeInserter`` can be used in clang-tidy checks in the following way:
|
||||||
/// \code
|
/// \code
|
||||||
|
/// #include "../ClangTidyCheck.h"
|
||||||
/// #include "../utils/IncludeInserter.h"
|
/// #include "../utils/IncludeInserter.h"
|
||||||
/// #include "clang/Frontend/CompilerInstance.h"
|
///
|
||||||
|
/// namespace clang {
|
||||||
|
/// namespace tidy {
|
||||||
///
|
///
|
||||||
/// class MyCheck : public ClangTidyCheck {
|
/// class MyCheck : public ClangTidyCheck {
|
||||||
/// public:
|
/// public:
|
||||||
/// void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
|
/// void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
|
||||||
/// Preprocessor *ModuleExpanderPP) override {
|
/// Preprocessor *ModuleExpanderPP) override {
|
||||||
/// Inserter = std::make_unique<IncludeInserter>(
|
/// Inserter.registerPreprocessor();
|
||||||
/// SM, getLangOpts(), utils::IncludeSorter::IS_Google);
|
|
||||||
/// PP->addPPCallbacks(Inserter->CreatePPCallbacks());
|
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// void registerMatchers(ast_matchers::MatchFinder* Finder) override { ... }
|
/// void registerMatchers(ast_matchers::MatchFinder* Finder) override { ... }
|
||||||
|
@ -43,39 +42,53 @@ namespace utils {
|
||||||
/// void check(
|
/// void check(
|
||||||
/// const ast_matchers::MatchFinder::MatchResult& Result) override {
|
/// const ast_matchers::MatchFinder::MatchResult& Result) override {
|
||||||
/// ...
|
/// ...
|
||||||
/// Inserter->CreateIncludeInsertion(
|
/// Inserter.createMainFileIncludeInsertion("path/to/Header.h",
|
||||||
/// Result.SourceManager->getMainFileID(), "path/to/Header.h",
|
|
||||||
/// /*IsAngled=*/false);
|
/// /*IsAngled=*/false);
|
||||||
/// ...
|
/// ...
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// private:
|
/// private:
|
||||||
/// std::unique_ptr<clang::tidy::utils::IncludeInserter> Inserter;
|
/// utils::IncludeInserter Inserter{utils::IncludeSorter::IS_Google};
|
||||||
/// };
|
/// };
|
||||||
|
/// } // namespace tidy
|
||||||
|
/// } // namespace clang
|
||||||
/// \endcode
|
/// \endcode
|
||||||
class IncludeInserter {
|
class IncludeInserter {
|
||||||
public:
|
public:
|
||||||
IncludeInserter(const SourceManager &SourceMgr, const LangOptions &LangOpts,
|
/// Initializes the IncludeInserter using the IncludeStyle \p Style.
|
||||||
IncludeSorter::IncludeStyle Style);
|
/// In most cases the \p Style will be retrieved from the ClangTidyOptions
|
||||||
~IncludeInserter();
|
/// using \code
|
||||||
|
/// Options.getLocalOrGlobal("IncludeStyle", <DefaultStyle>)
|
||||||
|
/// \endcode
|
||||||
|
explicit IncludeInserter(IncludeSorter::IncludeStyle Style);
|
||||||
|
|
||||||
/// Create ``PPCallbacks`` for registration with the compiler's preprocessor.
|
/// Registers this with the Preprocessor \p PP, must be called before this
|
||||||
std::unique_ptr<PPCallbacks> CreatePPCallbacks();
|
/// class is used.
|
||||||
|
void registerPreprocessor(Preprocessor *PP);
|
||||||
|
|
||||||
/// Creates a \p Header inclusion directive fixit. Returns ``llvm::None`` on
|
/// Creates a \p Header inclusion directive fixit in the File \p FileID.
|
||||||
/// error or if inclusion directive already exists.
|
/// Returns ``llvm::None`` on error or if the inclusion directive already
|
||||||
|
/// exists.
|
||||||
llvm::Optional<FixItHint>
|
llvm::Optional<FixItHint>
|
||||||
CreateIncludeInsertion(FileID FileID, llvm::StringRef Header, bool IsAngled);
|
createIncludeInsertion(FileID FileID, llvm::StringRef Header, bool IsAngled);
|
||||||
|
|
||||||
|
/// Creates a \p Header inclusion directive fixit in the main file.
|
||||||
|
/// Returns``llvm::None`` on error or if the inclusion directive already
|
||||||
|
/// exists.
|
||||||
|
llvm::Optional<FixItHint>
|
||||||
|
createMainFileIncludeInsertion(llvm::StringRef Header, bool IsAngled);
|
||||||
|
|
||||||
|
IncludeSorter::IncludeStyle getStyle() const { return Style; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AddInclude(StringRef FileName, bool IsAngled,
|
void addInclude(StringRef FileName, bool IsAngled,
|
||||||
SourceLocation HashLocation, SourceLocation EndLocation);
|
SourceLocation HashLocation, SourceLocation EndLocation);
|
||||||
|
|
||||||
IncludeSorter &getOrCreate(FileID FileID);
|
IncludeSorter &getOrCreate(FileID FileID);
|
||||||
|
|
||||||
llvm::DenseMap<FileID, std::unique_ptr<IncludeSorter>> IncludeSorterByFile;
|
llvm::DenseMap<FileID, std::unique_ptr<IncludeSorter>> IncludeSorterByFile;
|
||||||
llvm::DenseMap<FileID, std::set<std::string>> InsertedHeaders;
|
llvm::DenseMap<FileID, llvm::StringSet<>> InsertedHeaders;
|
||||||
const SourceManager &SourceMgr;
|
const SourceManager *SourceMgr{nullptr};
|
||||||
const IncludeSorter::IncludeStyle Style;
|
const IncludeSorter::IncludeStyle Style;
|
||||||
friend class IncludeInserterCallback;
|
friend class IncludeInserterCallback;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,8 +32,8 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(
|
||||||
MakeRule,
|
MakeRule,
|
||||||
StringRef Name, ClangTidyContext *Context)
|
StringRef Name, ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context), Rule(MakeRule(getLangOpts(), Options)),
|
: ClangTidyCheck(Name, Context), Rule(MakeRule(getLangOpts(), Options)),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
Inserter(
|
||||||
IncludeSorter::IS_LLVM)) {
|
Options.getLocalOrGlobal("IncludeStyle", IncludeSorter::IS_LLVM)) {
|
||||||
if (Rule)
|
if (Rule)
|
||||||
assert(llvm::all_of(Rule->Cases, hasExplanation) &&
|
assert(llvm::all_of(Rule->Cases, hasExplanation) &&
|
||||||
"clang-tidy checks must have an explanation by default;"
|
"clang-tidy checks must have an explanation by default;"
|
||||||
|
@ -44,8 +44,8 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(RewriteRule R,
|
||||||
StringRef Name,
|
StringRef Name,
|
||||||
ClangTidyContext *Context)
|
ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context), Rule(std::move(R)),
|
: ClangTidyCheck(Name, Context), Rule(std::move(R)),
|
||||||
IncludeStyle(Options.getLocalOrGlobal("IncludeStyle",
|
Inserter(
|
||||||
IncludeSorter::IS_LLVM)) {
|
Options.getLocalOrGlobal("IncludeStyle", IncludeSorter::IS_LLVM)) {
|
||||||
assert(llvm::all_of(Rule->Cases, hasExplanation) &&
|
assert(llvm::all_of(Rule->Cases, hasExplanation) &&
|
||||||
"clang-tidy checks must have an explanation by default;"
|
"clang-tidy checks must have an explanation by default;"
|
||||||
" explicitly provide an empty explanation if none is desired");
|
" explicitly provide an empty explanation if none is desired");
|
||||||
|
@ -53,15 +53,12 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(RewriteRule R,
|
||||||
|
|
||||||
void TransformerClangTidyCheck::registerPPCallbacks(
|
void TransformerClangTidyCheck::registerPPCallbacks(
|
||||||
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
|
||||||
// Only allocate and register the IncludeInsert when some `Case` will add
|
// Only register the IncludeInsert when some `Case` will add
|
||||||
// includes.
|
// includes.
|
||||||
if (Rule && llvm::any_of(Rule->Cases, [](const RewriteRule::Case &C) {
|
if (Rule && llvm::any_of(Rule->Cases, [](const RewriteRule::Case &C) {
|
||||||
return !C.AddedIncludes.empty();
|
return !C.AddedIncludes.empty();
|
||||||
})) {
|
}))
|
||||||
Inserter =
|
Inserter.registerPreprocessor(PP);
|
||||||
std::make_unique<IncludeInserter>(SM, getLangOpts(), IncludeStyle);
|
|
||||||
PP->addPPCallbacks(Inserter->CreatePPCallbacks());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransformerClangTidyCheck::registerMatchers(
|
void TransformerClangTidyCheck::registerMatchers(
|
||||||
|
@ -102,15 +99,15 @@ void TransformerClangTidyCheck::check(
|
||||||
Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
|
Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
|
||||||
|
|
||||||
for (const auto &I : Case.AddedIncludes) {
|
for (const auto &I : Case.AddedIncludes) {
|
||||||
Diag << Inserter->CreateIncludeInsertion(
|
Diag << Inserter.createMainFileIncludeInsertion(
|
||||||
Result.SourceManager->getMainFileID(), I.first,
|
I.first,
|
||||||
/*IsAngled=*/I.second == transformer::IncludeFormat::Angled);
|
/*IsAngled=*/I.second == transformer::IncludeFormat::Angled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransformerClangTidyCheck::storeOptions(
|
void TransformerClangTidyCheck::storeOptions(
|
||||||
ClangTidyOptions::OptionMap &Opts) {
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
Options.store(Opts, "IncludeStyle", IncludeStyle);
|
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|
|
@ -70,8 +70,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Optional<transformer::RewriteRule> Rule;
|
Optional<transformer::RewriteRule> Rule;
|
||||||
const IncludeSorter::IncludeStyle IncludeStyle;
|
IncludeInserter Inserter;
|
||||||
std::unique_ptr<IncludeInserter> Inserter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|
|
@ -33,9 +33,7 @@ public:
|
||||||
|
|
||||||
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
|
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
|
||||||
Preprocessor *ModuleExpanderPP) override {
|
Preprocessor *ModuleExpanderPP) override {
|
||||||
Inserter = std::make_unique<utils::IncludeInserter>(
|
Inserter.registerPreprocessor(PP);
|
||||||
SM, getLangOpts(), utils::IncludeSorter::IS_Google);
|
|
||||||
PP->addPPCallbacks(Inserter->CreatePPCallbacks());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerMatchers(ast_matchers::MatchFinder *Finder) override {
|
void registerMatchers(ast_matchers::MatchFinder *Finder) override {
|
||||||
|
@ -46,15 +44,15 @@ public:
|
||||||
auto Diag = diag(Result.Nodes.getNodeAs<DeclStmt>("stmt")->getBeginLoc(),
|
auto Diag = diag(Result.Nodes.getNodeAs<DeclStmt>("stmt")->getBeginLoc(),
|
||||||
"foo, bar");
|
"foo, bar");
|
||||||
for (StringRef Header : HeadersToInclude()) {
|
for (StringRef Header : HeadersToInclude()) {
|
||||||
Diag << Inserter->CreateIncludeInsertion(
|
Diag << Inserter.createMainFileIncludeInsertion(Header,
|
||||||
Result.SourceManager->getMainFileID(), Header, IsAngledInclude());
|
IsAngledInclude());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::vector<StringRef> HeadersToInclude() const = 0;
|
virtual std::vector<StringRef> HeadersToInclude() const = 0;
|
||||||
virtual bool IsAngledInclude() const = 0;
|
virtual bool IsAngledInclude() const = 0;
|
||||||
|
|
||||||
std::unique_ptr<utils::IncludeInserter> Inserter;
|
utils::IncludeInserter Inserter{utils::IncludeSorter::IS_Google};
|
||||||
};
|
};
|
||||||
|
|
||||||
class NonSystemHeaderInserterCheck : public IncludeInserterCheckBase {
|
class NonSystemHeaderInserterCheck : public IncludeInserterCheckBase {
|
||||||
|
|
Loading…
Reference in New Issue