summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
diff options
context:
space:
mode:
authorAlexander Kornienko <alexfh@google.com>2016-06-03 21:22:58 +0000
committerAlexander Kornienko <alexfh@google.com>2016-06-03 21:22:58 +0000
commitc0308c451bc1f2b19ea4c60b3606edf6e1651731 (patch)
treee8dc44a114298d15f1e4a5a26638b2f88403e76e /clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
parent94edaaaefba9727db12206de96c9046fe1629646 (diff)
downloadbcm5719-llvm-c0308c451bc1f2b19ea4c60b3606edf6e1651731.tar.gz
bcm5719-llvm-c0308c451bc1f2b19ea4c60b3606edf6e1651731.zip
[clang-tidy] modernize-use-auto: don't remove stars by default
Summary: By default, modernize-use-auto check will retain stars when replacing an explicit type with `auto`: `MyType *t = new MyType;` will be changed to `auto *t = new MyType;`, thus resulting in more consistency with the recommendations to use `auto *` for iterating over pointers in range-based for loops: http://llvm.org/docs/CodingStandards.html#beware-unnecessary-copies-with-auto The new `RemoveStars` option allows to revert to the old behavior: with the new option turned on the check will change `MyType *t = new MyType;` to `auto t = new MyType;`. Reviewers: aaron.ballman, sbenza Subscribers: Eugene.Zelenko, cfe-commits Differential Revision: http://reviews.llvm.org/D20917 llvm-svn: 271739
Diffstat (limited to 'clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp51
1 files changed, 32 insertions, 19 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
index 415ecdd83ad..1f1c140f027 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
@@ -243,6 +243,14 @@ StatementMatcher makeDeclWithNewMatcher() {
} // namespace
+UseAutoCheck::UseAutoCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ RemoveStars(Options.get("RemoveStars", 0)) {}
+
+void UseAutoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "RemoveStars", RemoveStars ? 1 : 0);
+}
+
void UseAutoCheck::registerMatchers(MatchFinder *Finder) {
// Only register the matchers for C++; the functionality currently does not
// provide any benefit to other languages, despite being benign.
@@ -311,7 +319,7 @@ void UseAutoCheck::replaceNew(const DeclStmt *D, ASTContext *Context) {
const QualType FirstDeclType = FirstDecl->getType().getCanonicalType();
- std::vector<SourceLocation> StarLocations;
+ std::vector<FixItHint> StarRemovals;
for (const auto *Dec : D->decls()) {
const auto *V = cast<VarDecl>(Dec);
// Ensure that every DeclStmt child is a VarDecl.
@@ -327,19 +335,23 @@ void UseAutoCheck::replaceNew(const DeclStmt *D, ASTContext *Context) {
if (!Context->hasSameUnqualifiedType(V->getType(), NewExpr->getType()))
return;
- // Remove explicitly written '*' from declarations where there's more than
- // one declaration in the declaration list.
- if (Dec == *D->decl_begin())
- continue;
-
- // All subsequent declarations should match the same non-decorated type.
+ // All subsequent variables in this declaration should have the same
+ // canonical type. For example, we don't want to use `auto` in
+ // `T *p = new T, **pp = new T*;`.
if (FirstDeclType != V->getType().getCanonicalType())
return;
- auto Q = V->getTypeSourceInfo()->getTypeLoc().getAs<PointerTypeLoc>();
- while (!Q.isNull()) {
- StarLocations.push_back(Q.getStarLoc());
- Q = Q.getNextTypeLoc().getAs<PointerTypeLoc>();
+ if (RemoveStars) {
+ // Remove explicitly written '*' from declarations where there's more than
+ // one declaration in the declaration list.
+ if (Dec == *D->decl_begin())
+ continue;
+
+ auto Q = V->getTypeSourceInfo()->getTypeLoc().getAs<PointerTypeLoc>();
+ while (!Q.isNull()) {
+ StarRemovals.push_back(FixItHint::CreateRemoval(Q.getStarLoc()));
+ Q = Q.getNextTypeLoc().getAs<PointerTypeLoc>();
+ }
}
}
@@ -347,19 +359,20 @@ void UseAutoCheck::replaceNew(const DeclStmt *D, ASTContext *Context) {
// is the same as the initializer, just more CV-qualified. However, TypeLoc
// information is not reliable where CV qualifiers are concerned so we can't
// do anything about this case for now.
- SourceRange Range(
- FirstDecl->getTypeSourceInfo()->getTypeLoc().getSourceRange());
+ TypeLoc Loc = FirstDecl->getTypeSourceInfo()->getTypeLoc();
+ if (!RemoveStars) {
+ while (Loc.getTypeLocClass() == TypeLoc::Pointer ||
+ Loc.getTypeLocClass() == TypeLoc::Qualified)
+ Loc = Loc.getNextTypeLoc();
+ }
+ SourceRange Range(Loc.getSourceRange());
auto Diag = diag(Range.getBegin(), "use auto when initializing with new"
" to avoid duplicating the type name");
// Space after 'auto' to handle cases where the '*' in the pointer type is
// next to the identifier. This avoids changing 'int *p' into 'autop'.
- Diag << FixItHint::CreateReplacement(Range, "auto ");
-
- // Remove '*' from declarations using the saved star locations.
- for (const auto &Loc : StarLocations) {
- Diag << FixItHint::CreateReplacement(Loc, "");
- }
+ Diag << FixItHint::CreateReplacement(Range, RemoveStars ? "auto " : "auto")
+ << StarRemovals;
}
void UseAutoCheck::check(const MatchFinder::MatchResult &Result) {
OpenPOWER on IntegriCloud