[clang-tidy] RenamerClangTidy wont emit fixes in scratch space

Prevent fixes being displayed if usages are found in the scratch buffer.
See [[ https://bugs.llvm.org/show_bug.cgi?id=46219 | Fix-It hints are being generated in the ScratchBuffer ]].
It may be wise down the line to put in a general fix in clang-tidy to prevent ScratchBuffer replacements being applied, but for now this will help.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D82162
This commit is contained in:
Nathan James 2020-06-22 18:26:17 +01:00
parent 9a8b041144
commit 6ae0f5f3e1
No known key found for this signature in database
GPG Key ID: CC007AFCDA90AA5F
2 changed files with 40 additions and 15 deletions

View File

@ -156,14 +156,17 @@ void RenamerClangTidyCheck::addUsage(
// is already in there // is already in there
RenamerClangTidyCheck::NamingCheckFailure &Failure = RenamerClangTidyCheck::NamingCheckFailure &Failure =
NamingCheckFailures[Decl]; NamingCheckFailures[Decl];
if (!Failure.RawUsageLocs.insert(FixLocation.getRawEncoding()).second)
return;
if (!Failure.ShouldFix()) if (!Failure.ShouldFix())
return; return;
if (SourceMgr && SourceMgr->isWrittenInScratchSpace(FixLocation))
Failure.FixStatus = RenamerClangTidyCheck::ShouldFixStatus::InsideMacro;
if (!utils::rangeCanBeFixed(Range, SourceMgr)) if (!utils::rangeCanBeFixed(Range, SourceMgr))
Failure.FixStatus = RenamerClangTidyCheck::ShouldFixStatus::InsideMacro; Failure.FixStatus = RenamerClangTidyCheck::ShouldFixStatus::InsideMacro;
Failure.RawUsageLocs.insert(FixLocation.getRawEncoding());
} }
void RenamerClangTidyCheck::addUsage(const NamedDecl *Decl, SourceRange Range, void RenamerClangTidyCheck::addUsage(const NamedDecl *Decl, SourceRange Range,
@ -248,13 +251,15 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Decl = if (const auto *Decl =
Result.Nodes.getNodeAs<CXXConstructorDecl>("classRef")) { Result.Nodes.getNodeAs<CXXConstructorDecl>("classRef")) {
addUsage(Decl->getParent(), Decl->getNameInfo().getSourceRange()); addUsage(Decl->getParent(), Decl->getNameInfo().getSourceRange(),
Result.SourceManager);
for (const auto *Init : Decl->inits()) { for (const auto *Init : Decl->inits()) {
if (!Init->isWritten() || Init->isInClassMemberInitializer()) if (!Init->isWritten() || Init->isInClassMemberInitializer())
continue; continue;
if (const FieldDecl *FD = Init->getAnyMember()) if (const FieldDecl *FD = Init->getAnyMember())
addUsage(FD, SourceRange(Init->getMemberLocation())); addUsage(FD, SourceRange(Init->getMemberLocation()),
Result.SourceManager);
// Note: delegating constructors and base class initializers are handled // Note: delegating constructors and base class initializers are handled
// via the "typeLoc" matcher. // via the "typeLoc" matcher.
} }
@ -271,7 +276,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
// we want instead to replace the next token, that will be the identifier. // we want instead to replace the next token, that will be the identifier.
Range.setBegin(CharSourceRange::getTokenRange(Range).getEnd()); Range.setBegin(CharSourceRange::getTokenRange(Range).getEnd());
addUsage(Decl->getParent(), Range); addUsage(Decl->getParent(), Range, Result.SourceManager);
return; return;
} }
@ -289,7 +294,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
// further TypeLocs handled below // further TypeLocs handled below
if (Decl) { if (Decl) {
addUsage(Decl, Loc->getSourceRange()); addUsage(Decl, Loc->getSourceRange(), Result.SourceManager);
return; return;
} }
@ -300,7 +305,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
SourceRange Range(Ref.getTemplateNameLoc(), Ref.getTemplateNameLoc()); SourceRange Range(Ref.getTemplateNameLoc(), Ref.getTemplateNameLoc());
if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl)) { if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl)) {
if (const NamedDecl *TemplDecl = ClassDecl->getTemplatedDecl()) if (const NamedDecl *TemplDecl = ClassDecl->getTemplatedDecl())
addUsage(TemplDecl, Range); addUsage(TemplDecl, Range, Result.SourceManager);
return; return;
} }
} }
@ -308,7 +313,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto &Ref = if (const auto &Ref =
Loc->getAs<DependentTemplateSpecializationTypeLoc>()) { Loc->getAs<DependentTemplateSpecializationTypeLoc>()) {
if (const TagDecl *Decl = Ref.getTypePtr()->getAsTagDecl()) if (const TagDecl *Decl = Ref.getTypePtr()->getAsTagDecl())
addUsage(Decl, Loc->getSourceRange()); addUsage(Decl, Loc->getSourceRange(), Result.SourceManager);
return; return;
} }
} }
@ -317,7 +322,7 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
Result.Nodes.getNodeAs<NestedNameSpecifierLoc>("nestedNameLoc")) { Result.Nodes.getNodeAs<NestedNameSpecifierLoc>("nestedNameLoc")) {
if (const NestedNameSpecifier *Spec = Loc->getNestedNameSpecifier()) { if (const NestedNameSpecifier *Spec = Loc->getNestedNameSpecifier()) {
if (const NamespaceDecl *Decl = Spec->getAsNamespace()) { if (const NamespaceDecl *Decl = Spec->getAsNamespace()) {
addUsage(Decl, Loc->getLocalSourceRange()); addUsage(Decl, Loc->getLocalSourceRange(), Result.SourceManager);
return; return;
} }
} }
@ -325,7 +330,8 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Decl = Result.Nodes.getNodeAs<UsingDecl>("using")) { if (const auto *Decl = Result.Nodes.getNodeAs<UsingDecl>("using")) {
for (const auto *Shadow : Decl->shadows()) for (const auto *Shadow : Decl->shadows())
addUsage(Shadow->getTargetDecl(), Decl->getNameInfo().getSourceRange()); addUsage(Shadow->getTargetDecl(), Decl->getNameInfo().getSourceRange(),
Result.SourceManager);
return; return;
} }
@ -371,14 +377,14 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
// Fix using namespace declarations. // Fix using namespace declarations.
if (const auto *UsingNS = dyn_cast<UsingDirectiveDecl>(Decl)) if (const auto *UsingNS = dyn_cast<UsingDirectiveDecl>(Decl))
addUsage(UsingNS->getNominatedNamespaceAsWritten(), addUsage(UsingNS->getNominatedNamespaceAsWritten(),
UsingNS->getIdentLocation()); UsingNS->getIdentLocation(), Result.SourceManager);
if (!Decl->getIdentifier() || Decl->getName().empty() || Decl->isImplicit()) if (!Decl->getIdentifier() || Decl->getName().empty() || Decl->isImplicit())
return; return;
const auto *Canonical = cast<NamedDecl>(Decl->getCanonicalDecl()); const auto *Canonical = cast<NamedDecl>(Decl->getCanonicalDecl());
if (Canonical != Decl) { if (Canonical != Decl) {
addUsage(Canonical, Decl->getLocation()); addUsage(Canonical, Decl->getLocation(), Result.SourceManager);
return; return;
} }
@ -386,7 +392,8 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Value = Result.Nodes.getNodeAs<ValueDecl>("decl")) { if (const auto *Value = Result.Nodes.getNodeAs<ValueDecl>("decl")) {
if (const Type *TypePtr = Value->getType().getTypePtrOrNull()) { if (const Type *TypePtr = Value->getType().getTypePtrOrNull()) {
if (const auto *Typedef = TypePtr->getAs<TypedefType>()) if (const auto *Typedef = TypePtr->getAs<TypedefType>())
addUsage(Typedef->getDecl(), Value->getSourceRange()); addUsage(Typedef->getDecl(), Value->getSourceRange(),
Result.SourceManager);
} }
} }
@ -394,11 +401,13 @@ void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *Value = Result.Nodes.getNodeAs<FunctionDecl>("decl")) { if (const auto *Value = Result.Nodes.getNodeAs<FunctionDecl>("decl")) {
if (const auto *Typedef = if (const auto *Typedef =
Value->getReturnType().getTypePtr()->getAs<TypedefType>()) Value->getReturnType().getTypePtr()->getAs<TypedefType>())
addUsage(Typedef->getDecl(), Value->getSourceRange()); addUsage(Typedef->getDecl(), Value->getSourceRange(),
Result.SourceManager);
for (const ParmVarDecl *Param : Value->parameters()) { for (const ParmVarDecl *Param : Value->parameters()) {
if (const TypedefType *Typedef = if (const TypedefType *Typedef =
Param->getType().getTypePtr()->getAs<TypedefType>()) Param->getType().getTypePtr()->getAs<TypedefType>())
addUsage(Typedef->getDecl(), Value->getSourceRange()); addUsage(Typedef->getDecl(), Value->getSourceRange(),
Result.SourceManager);
} }
} }

View File

@ -562,3 +562,19 @@ void ReferenceBadNamedFunction() {
} }
} // namespace redecls } // namespace redecls
namespace scratchspace {
#define DUP(Tok) Tok
#define M1(Tok) DUP(badName##Tok())
// We don't want a warning here as the call to this in Foo is in a scratch
// buffer so its fix-it wouldn't be applied, resulting in invalid code.
void badNameWarn();
void Foo() {
M1(Warn);
}
#undef M1
#undef DUP
} // namespace scratchspace