[clang-tools-extra] r247399 - Another patch for modernize-loop-convert.
Author: angelgarcia Date: Fri Sep 11 05:02:07 2015 New Revision: 247399 URL: http://llvm.org/viewvc/llvm-project?rev=247399&view=rev Log: Another patch for modernize-loop-convert. Summary: 1. Avoid converting loops that iterate over the size of a container and don't use its elements, as this would result in an unused-result warning. 2. Never capture the elements by value on lambdas, thus avoiding doing unnecessary copies and errors with non-copyable types. 3. The 'const auto &' instead of 'auto &' substitution on const containers now works on arrays and pseudoarrays as well. 4. The error about multiple replacements in the same macro call is now documented in the tests (not solved though). 5. Due to [1], I had to add a dummy usage of the range element (like "(void) *It;" or similars) on the tests that had empty loops. 6. I removed the braces from the CHECK comments. I think that there is no need for them, and they confuse vim. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D12734 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-negative.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=247399&r1=247398&r2=247399&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Fri Sep 11 05:02:07 2015 @@ -381,6 +381,20 @@ static bool usagesReturnRValues(const Us return true; } +/// \brief Returns true if the container is const-qualified. +static bool containerIsConst(const Expr *ContainerExpr, bool Dereference) { + if (const auto *VDec = getReferencedVariable(ContainerExpr)) { +QualType CType = VDec->getType(); +if (Dereference) { + if (!CType->isPointerType()) +return false; + CType = CType->getPointeeType(); +} +return CType.isConstQualified(); + } + return false; +} + LoopConvertCheck::LoopConvertCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), TUInfo(new TUTrackingInfo), MinConfidence(StringSwitch( @@ -401,6 +415,11 @@ void LoopConvertCheck::doConversion( StringRef ContainerString, const UsageResult &Usages, const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit, const ForStmt *TheLoop, RangeDescriptor Descriptor) { + // If there aren't any usages, converting the loop would generate an unused + // variable warning. + if (Usages.size() == 0) +return; + auto Diag = diag(TheLoop->getForLoc(), "use range-based for loop instead"); std::string VarName; @@ -436,11 +455,23 @@ void LoopConvertCheck::doConversion( VarName = Namer.createIndexName(); // First, replace all usages of the array subscript expression with our new // variable. -for (const auto &I : Usages) { - std::string ReplaceText = I.IsArrow ? VarName + "." : VarName; +for (const auto &Usage : Usages) { + std::string ReplaceText; + if (Usage.Expression) { +// If this is an access to a member through the arrow operator, after +// the replacement it must be accessed through the '.' operator. +ReplaceText = Usage.Kind == Usage::UK_MemberThroughArrow ? VarName + "." + : VarName; + } else { +// The Usage expression is only null in case of lambda captures (which +// are VarDecl). If the index is captured by value, add '&' to capture +// by reference instead. +ReplaceText = +Usage.Kind == Usage::UK_CaptureByCopy ? "&" + VarName : VarName; + } TUInfo->getReplacedVars().insert(std::make_pair(TheLoop, IndexVar)); Diag << FixItHint::CreateReplacement( - CharSourceRange::getTokenRange(I.Range), ReplaceText); + CharSourceRange::getTokenRange(Usage.Range), ReplaceText); } } @@ -537,16 +568,24 @@ void LoopConvertCheck::findAndVerifyUsag if (FixerKind == LFK_Array) { // The array being indexed by IndexVar was discovered during traversal. ContainerExpr = Finder.getContainerIndexed()->IgnoreParenImpCasts(); + // Very few loops are over expressions that generate arrays rather than // a
[clang-tools-extra] r247889 - Add a test to modernize-loop-convert.
Author: angelgarcia Date: Thu Sep 17 09:25:39 2015 New Revision: 247889 URL: http://llvm.org/viewvc/llvm-project?rev=247889&view=rev Log: Add a test to modernize-loop-convert. Summary: Add the test about replacements in several arguments of the same macro call, now that the problem has been fixed. Reviewers: alexfh Subscribers: cfe-commits, klimek Differential Revision: http://reviews.llvm.org/D12933 Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp?rev=247889&r1=247888&r2=247889&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Thu Sep 17 09:25:39 2015 @@ -702,21 +702,15 @@ void messing_with_macros() { printf("Value: %d\n", CONT arr[i]); } - // FIXME: Right now, clang-tidy does not allow to make insertions in several - // arguments of the same macro call. The following code: - // \code - // for (int i = 0; i < N; ++i) { - //TWO_PARAM(arr[i], arr[i]); - //THREE_PARAM(arr[i], arr[i], arr[i]); - // } - // \endcode - // Should be converted to this: - // \code - // for (auto & elem : arr) { - //TWO_PARAM(elem, elem); - //THREE_PARAM(elem, elem, elem); - // } - // \endcode + // Multiple macro arguments. + for (int i = 0; i < N; ++i) { +TWO_PARAM(arr[i], arr[i]); +THREE_PARAM(arr[i], arr[i], arr[i]); + } + // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & elem : arr) + // CHECK-FIXES-NEXT: TWO_PARAM(elem, elem); + // CHECK-FIXES-NEXT: THREE_PARAM(elem, elem, elem); } } // namespace Macros ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r247987 - Update clang-tidy documentation.
Author: angelgarcia Date: Fri Sep 18 09:08:57 2015 New Revision: 247987 URL: http://llvm.org/viewvc/llvm-project?rev=247987&view=rev Log: Update clang-tidy documentation. Summary: Update documentation of the modernize module with clang-modernize's documentation. Subscribers: cfe-commits, klimek, alexfh Differential Revision: http://reviews.llvm.org/D12961 Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-pass-by-value.rst clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-replace-auto-ptr.rst clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-nullptr.rst Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst?rev=247987&r1=247986&r2=247987&view=diff == --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst Fri Sep 18 09:08:57 2015 @@ -1,4 +1,253 @@ modernize-loop-convert == +This check converts ``for(...; ...; ...)`` loops to use the new range-based +loops in C++11. +Three kinds of loops can be converted: + +- Loops over statically allocated arrays. +- Loops over containers, using iterators. +- Loops over array-like containers, using ``operator[]`` and ``at()``. + +MinConfidence option + + +risky +- + +In loops where the container expression is more complex than just a +reference to a declared expression (a variable, function, enum, etc.), +and some part of it appears elsewhere in the loop, we lower our confidence +in the transformation due to the increased risk of changing semantics. +Transformations for these loops are marked as `risky`, and thus will only +be converted if the minimum required confidence level is set to ``risky``. + +.. code-block:: c++ + + int arr[10][20]; + int l = 5; + + for (int j = 0; j < 20; ++j) +int k = arr[l][j] + l; // using l outside arr[l] is considered risky + + for (int i = 0; i < obj.getVector().size(); ++i) +obj.foo(10); // using 'obj' is considered risky + +See +:ref:`Range-based loops evaluate end() only once` +for an example of an incorrect transformation when the minimum required confidence +level is set to `risky`. + +reasonable (Default) + + +If a loop calls ``.end()`` or ``.size()`` after each iteration, the +transformation for that loop is marked as `reasonable`, and thus will +be converted if the required confidence level is set to ``reasonable`` +(default) or lower. + +.. code-block:: c++ + + // using size() is considered reasonable + for (int i = 0; i < container.size(); ++i) +cout << container[i]; + +safe + + +Any other loops that do not match the above criteria to be marked as +`risky` or `reasonable` are marked `safe`, and thus will be converted +if the required confidence level is set to ``safe`` or lower. + +.. code-block:: c++ + + int arr[] = {1,2,3}; + + for (int i = 0; i < 3; ++i) +cout << arr[i]; + +Example +=== + +Original: + +.. code-block:: c++ + + const int N = 5; + int arr[] = {1,2,3,4,5}; + vector v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + + // safe transform + for (int i = 0; i < N; ++i) +cout << arr[i]; + + // reasonable transform + for (vector::iterator it = v.begin(); it != v.end(); ++it) +cout << *it;* + + // reasonable transform + for (int i = 0; i < v.size(); ++i) +cout << v[i]; + +After transformation with confidence level set to ``reasonable`` (default): + +.. code-block:: c++ + + const int N = 5; + int arr[] = {1,2,3,4,5}; + vector v; + v.push_back(1); + v.push_back(2); + v.push_back(3); + + // safe transform + for (auto & elem : arr) +cout << elem; + + // reasonable transform + for (auto & elem : v) +cout << elem; + + // reasonable transform + for (auto & elem : v) +cout << elem; + +Limitations +=== + +There are certain situations where the tool may erroneously perform +transformations that remove information and change semantics. Users of the tool +should be aware of the behaviour and limitations of the transform outlined by +the cases below. + +Comments inside loop headers + + +Comments inside the original loop header are ignored and deleted when +transformed. + +.. code-block:: c++ + + for (int i = 0; i < N; /* This will be deleted */ ++i) { } + +Range-based loops evaluate end() only once +-- + +The C++11 range-based for loop calls ``.end()`` only once during the +initialization of the loop. If in the original loop ``.end()`` is called after +each iteration the
[clang-tools-extra] r248144 - Refactor LoopConvertCheck.
Author: angelgarcia Date: Mon Sep 21 04:32:59 2015 New Revision: 248144 URL: http://llvm.org/viewvc/llvm-project?rev=248144&view=rev Log: Refactor LoopConvertCheck. Summary: Reorder the code in a more logical and understandable way. Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D12797 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=248144&r1=248143&r2=248144&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Mon Sep 21 04:32:59 2015 @@ -396,6 +396,10 @@ static bool containerIsConst(const Expr return false; } +LoopConvertCheck::RangeDescriptor::RangeDescriptor() +: ContainerNeedsDereference(false), DerefByConstRef(false), + DerefByValue(false), IsTriviallyCopyable(false) {} + LoopConvertCheck::LoopConvertCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), TUInfo(new TUTrackingInfo), MinConfidence(StringSwitch( @@ -409,19 +413,25 @@ void LoopConvertCheck::storeOptions(Clan Options.store(Opts, "MinConfidence", Confs[static_cast(MinConfidence)]); } +void LoopConvertCheck::registerMatchers(MatchFinder *Finder) { + // Only register the matchers for C++. Because this checker is used for + // modernization, it is reasonable to run it on any C++ standard with the + // assumption the user is trying to modernize their codebase. + if (!getLangOpts().CPlusPlus) +return; + + Finder->addMatcher(makeArrayLoopMatcher(), this); + Finder->addMatcher(makeIteratorLoopMatcher(), this); + Finder->addMatcher(makePseudoArrayLoopMatcher(), this); +} + /// \brief Computes the changes needed to convert a given for loop, and -/// applies it. +/// applies them. void LoopConvertCheck::doConversion( ASTContext *Context, const VarDecl *IndexVar, const VarDecl *MaybeContainer, -StringRef ContainerString, const UsageResult &Usages, -const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit, -const ForStmt *TheLoop, RangeDescriptor Descriptor) { - // If there aren't any usages, converting the loop would generate an unused - // variable warning. - if (Usages.size() == 0) -return; - - auto Diag = diag(TheLoop->getForLoc(), "use range-based for loop instead"); +const UsageResult &Usages, const DeclStmt *AliasDecl, bool AliasUseRequired, +bool AliasFromForInit, const ForStmt *Loop, RangeDescriptor Descriptor) { + auto Diag = diag(Loop->getForLoc(), "use range-based for loop instead"); std::string VarName; bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl; @@ -452,7 +462,7 @@ void LoopConvertCheck::doConversion( } else { VariableNamer Namer(&TUInfo->getGeneratedDecls(), &TUInfo->getParentFinder().getStmtToParentStmtMap(), -TheLoop, IndexVar, MaybeContainer, Context); +Loop, IndexVar, MaybeContainer, Context); VarName = Namer.createIndexName(); // First, replace all usages of the array subscript expression with our new // variable. @@ -470,70 +480,46 @@ void LoopConvertCheck::doConversion( ReplaceText = Usage.Kind == Usage::UK_CaptureByCopy ? "&" + VarName : VarName; } - TUInfo->getReplacedVars().insert(std::make_pair(TheLoop, IndexVar)); + TUInfo->getReplacedVars().insert(std::make_pair(Loop, IndexVar)); Diag << FixItHint::CreateReplacement( CharSourceRange::getTokenRange(Usage.Range), ReplaceText); } } // Now, we need to construct the new range expression. - SourceRange ParenRange(TheLoop->getLParenLoc(), TheLoop->getRParenLoc()); + SourceRange ParenRange(Loop->getLParenLoc(), Loop->getRParenLoc()); - QualType AutoRefType = Context->getAutoDeductType(); + QualType AutoType = Context->getAutoDeductType(); // If the new variable name is from the aliased variable, then the reference // type for the new variable should only be used if the aliased variable was // declared as a reference. if (!VarNameFromAlias || AliasVarIsRef) { -// If an iterator's operator*() returns a 'T&' we can bind that to 'auto&'. -// If operator*() returns 'T' we can bind that to 'auto&&' which will deduce -// to 'T&&&'. -if (Descriptor.DerefByValue) { +if (Descriptor.DerefByConstRef) { + AutoType = + Context->getLValueReferenceType(Context->getConstType(AutoType)); +} else if (Descriptor.DerefByValue) { i
[clang-tools-extra] r248153 - Replace references to "transform" with references to "check" where neccessary in the documentation.
Author: angelgarcia Date: Mon Sep 21 07:53:30 2015 New Revision: 248153 URL: http://llvm.org/viewvc/llvm-project?rev=248153&view=rev Log: Replace references to "transform" with references to "check" where neccessary in the documentation. Summary: Replace references to "transform" with references to "check" where neccessary in the documentation. Reviewers: alexfh Subscribers: cfe-commits, klimek Differential Revision: http://reviews.llvm.org/D13006 Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-pass-by-value.rst clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-replace-auto-ptr.rst clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-nullptr.rst Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst?rev=248153&r1=248152&r2=248153&view=diff == --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-loop-convert.rst Mon Sep 21 07:53:30 2015 @@ -81,19 +81,19 @@ Original: v.push_back(2); v.push_back(3); - // safe transform + // safe conversion for (int i = 0; i < N; ++i) cout << arr[i]; - // reasonable transform + // reasonable conversion for (vector::iterator it = v.begin(); it != v.end(); ++it) cout << *it;* - // reasonable transform + // reasonable conversion for (int i = 0; i < v.size(); ++i) cout << v[i]; -After transformation with confidence level set to ``reasonable`` (default): +After applying the check with minimum confidence level set to ``reasonable`` (default): .. code-block:: c++ @@ -104,15 +104,15 @@ After transformation with confidence lev v.push_back(2); v.push_back(3); - // safe transform + // safe conversion for (auto & elem : arr) cout << elem; - // reasonable transform + // reasonable conversion for (auto & elem : v) cout << elem; - // reasonable transform + // reasonable conversion for (auto & elem : v) cout << elem; @@ -121,7 +121,7 @@ Limitations There are certain situations where the tool may erroneously perform transformations that remove information and change semantics. Users of the tool -should be aware of the behaviour and limitations of the transform outlined by +should be aware of the behaviour and limitations of the check outlined by the cases below. Comments inside loop headers @@ -223,7 +223,7 @@ performed. Pointers and references to containers ^ -While most of the transform's risk analysis is dedicated to determining whether +While most of the check's risk analysis is dedicated to determining whether the iterator or container was modified within the loop, it is possible to circumvent the analysis by accessing and modifying the container through a pointer or reference. @@ -231,7 +231,7 @@ pointer or reference. If the container were directly used instead of using the pointer or reference the following transformation would have only been applied at the ``risky`` level since calling a member function of the container is considered `risky`. -The transform cannot identify expressions associated with the container that are +The check cannot identify expressions associated with the container that are different than the one used in the loop header, therefore the transformation below ends up being performed at the ``safe`` level. Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-pass-by-value.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-pass-by-value.rst?rev=248153&r1=248152&r2=248153&view=diff == --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-pass-by-value.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-pass-by-value.rst Mon Sep 21 07:53:30 2015 @@ -2,10 +2,10 @@ modernize-pass-by-value === With move semantics added to the language and the standard library updated with -move constructors added for many types it is now interesting to take an argument -directly by value, instead of by const-reference, and then copy. This -transformation allows the compiler to take care of choosing the best way to -construct the copy. +move constructors added for many types it is now interesting to take an +argument directly by value, instead of by const-reference, and then copy. This +check allows the compiler to take care of choosing the best way to construct +the copy. The transformation is usually beneficial when
[clang-tools-extra] r248489 - Solve comment on rL248418.
Author: angelgarcia Date: Thu Sep 24 08:26:28 2015 New Revision: 248489 URL: http://llvm.org/viewvc/llvm-project?rev=248489&view=rev Log: Solve comment on rL248418. Summary: Solve comment on rL248418. Reviewers: alexfh Subscribers: cfe-commits, klimek Differential Revision: http://reviews.llvm.org/D13129 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=248489&r1=248488&r2=248489&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Thu Sep 24 08:26:28 2015 @@ -394,9 +394,7 @@ static bool containerIsConst(const Expr // If VDec is a reference to a container, Dereference is false, // but we still need to check the const-ness of the underlying container // type. -if (const auto &RT = CType->getAs()) { - CType = RT->getPointeeType(); -} +CType = CType.getNonReferenceType(); return CType.isConstQualified(); } return false; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r248507 - Remove dangling parenthesis.
Author: angelgarcia Date: Thu Sep 24 10:29:46 2015 New Revision: 248507 URL: http://llvm.org/viewvc/llvm-project?rev=248507&view=rev Log: Remove dangling parenthesis. Summary: Remove parenthesis surrounding the new loop index. Reviewers: klimek Subscribers: cfe-commits, klimek Differential Revision: http://reviews.llvm.org/D13133 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=248507&r1=248506&r2=248507&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Thu Sep 24 10:29:46 2015 @@ -472,11 +472,21 @@ void LoopConvertCheck::doConversion( // variable. for (const auto &Usage : Usages) { std::string ReplaceText; + SourceRange Range = Usage.Range; if (Usage.Expression) { // If this is an access to a member through the arrow operator, after // the replacement it must be accessed through the '.' operator. ReplaceText = Usage.Kind == Usage::UK_MemberThroughArrow ? VarName + "." : VarName; +auto Parents = Context->getParents(*Usage.Expression); +if (Parents.size() == 1) { + if (const auto *Paren = Parents[0].get()) { +// Usage.Expression will be replaced with the new index variable, +// and parenthesis around a simple DeclRefExpr can always be +// removed. +Range = Paren->getSourceRange(); + } +} } else { // The Usage expression is only null in case of lambda captures (which // are VarDecl). If the index is captured by value, add '&' to capture @@ -486,7 +496,7 @@ void LoopConvertCheck::doConversion( } TUInfo->getReplacedVars().insert(std::make_pair(Loop, IndexVar)); Diag << FixItHint::CreateReplacement( - CharSourceRange::getTokenRange(Usage.Range), ReplaceText); + CharSourceRange::getTokenRange(Range), ReplaceText); } } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp?rev=248507&r1=248506&r2=248507&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Thu Sep 24 10:29:46 2015 @@ -199,7 +199,7 @@ void f() { } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : s) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x); S *ps; for (S::iterator it = ps->begin(), e = ps->end(); it != e; ++it) { @@ -207,7 +207,7 @@ void f() { } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & p : *ps) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (p).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", p.x); for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { printf("s has value %d\n", it->x); @@ -228,7 +228,7 @@ void f() { } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : s) - // CHECK-FIXES-NEXT: (elem).x = 3; + // CHECK-FIXES-NEXT: elem.x = 3; for (S::iterator it = s.begin(), e = s.end(); it != e; ++it) { it->nonConstFun(4, 5); @@ -250,7 +250,7 @@ void f() { } // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : u) - // CHECK-FIXES-NEXT: printf("s has value %d\n", (elem).x); + // CHECK-FIXES-NEXT: printf("s has value %d\n", elem.x); U::iterator A; for (U::iterator i = u.begin(), e = u.end(); i != e; ++i) @@ -321,6 +321,21 @@ void f() { (void) *I; } } + + dependent dpp; + for (dependent::iterator I = dpp.begin(), E = dpp.end(); I != E; ++I) { +printf("%d\n", (**I).x); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & elem : dpp) + // CHECK-FIXES-NEXT: printf("%d\n", (*elem).x); + + for (dependent::iterator I = dpp.begin(), E = dpp.end(); I != E; ++I) { +printf("%d\n", (*I)->x); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead +
[clang-tools-extra] r248785 - Create modernize-make-unique check.
Author: angelgarcia Date: Tue Sep 29 04:36:41 2015 New Revision: 248785 URL: http://llvm.org/viewvc/llvm-project?rev=248785&view=rev Log: Create modernize-make-unique check. Summary: create a check that replaces 'std::unique_ptr(new type(args...))' with 'std::make_unique(args...)'. It was on the list of "Ideas for new Tools". It needs to be tested more carefully, but first I wanted to know if you think it is worth the effort. Reviewers: klimek Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D13166 Added: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt?rev=248785&r1=248784&r2=248785&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Tue Sep 29 04:36:41 2015 @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyModernizeModule LoopConvertCheck.cpp LoopConvertUtils.cpp + MakeUniqueCheck.cpp ModernizeTidyModule.cpp PassByValueCheck.cpp ReplaceAutoPtrCheck.cpp Added: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp?rev=248785&view=auto == --- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (added) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp Tue Sep 29 04:36:41 2015 @@ -0,0 +1,108 @@ +//===--- MakeUniqueCheck.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 "MakeUniqueCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace modernize { + +const char PointerType[] = "pointerType"; +const char ConstructorCall[] = "constructorCall"; +const char NewExpression[] = "newExpression"; + +void MakeUniqueCheck::registerMatchers(MatchFinder *Finder) { + if (getLangOpts().CPlusPlus11) { +Finder->addMatcher( +cxxBindTemporaryExpr(has( +cxxConstructExpr( + hasType(qualType(hasDeclaration(classTemplateSpecializationDecl( +matchesName("::std::unique_ptr"), +templateArgumentCountIs(1), +hasTemplateArgument( +0, templateArgument( + refersToType(qualType().bind(PointerType, +argumentCountIs(1), +hasArgument(0, cxxNewExpr(hasType(pointsTo(qualType( + equalsBoundNode(PointerType) + .bind(NewExpression))) +.bind(ConstructorCall))), +this); + } +} + +void MakeUniqueCheck::check(const MatchFinder::MatchResult &Result) { + SourceManager &SM = *Result.SourceManager; + const auto *Construct = + Result.Nodes.getNodeAs(ConstructorCall); + const auto *New = Result.Nodes.getNodeAs(NewExpression); + const auto *Type = Result.Nodes.getNodeAs(PointerType); + + SourceLocation ConstructCallStart = Construct->getExprLoc(); + + bool Invalid = false; + StringRef ExprStr = Lexer::getSourceText( + CharSourceRange::getCharRange( + ConstructCallStart, Construct->getParenOrBraceRange().getBegin()), + SM, LangOptions(), &Invalid); + if (Invalid) +return; + + auto Diag = diag(ConstructCallStart, "use std::make_unique instead"); + + // Find the location of the template's left angle. + size_t LAngle = ExprStr.find("<"); + SourceLocation ConstructCallEnd; + if (LAngle == StringRef::npos) { +// If the template argument is missing (because it is part of the alias) +// we have to add it back. +ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size()); +Diag << FixItHint::CreateInsertion(ConstructCallEnd, + "<" + Type->getAsString() + ">"); + } else { +ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle); + } + + Diag << FixItHint::CreateReplacement( + C
[clang-tools-extra] r248994 - Add support for 'cbegin()' and 'cend()' on modernize-loop-convert.
Author: angelgarcia Date: Thu Oct 1 03:57:11 2015 New Revision: 248994 URL: http://llvm.org/viewvc/llvm-project?rev=248994&view=rev Log: Add support for 'cbegin()' and 'cend()' on modernize-loop-convert. Summary: This fixes https://llvm.org/bugs/show_bug.cgi?id=22196 . Also add a non-trivially copyable type to fix some tests that were meant to be about using const-refs, but were changed in r248438. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13292 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=248994&r1=248993&r2=248994&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Thu Oct 1 03:57:11 2015 @@ -112,8 +112,9 @@ StatementMatcher makeArrayLoopMatcher() /// - If the end iterator variable 'g' is defined, it is the same as 'f'. StatementMatcher makeIteratorLoopMatcher() { StatementMatcher BeginCallMatcher = - cxxMemberCallExpr(argumentCountIs(0), -callee(cxxMethodDecl(hasName("begin" + cxxMemberCallExpr( + argumentCountIs(0), + callee(cxxMethodDecl(anyOf(hasName("begin"), hasName("cbegin") .bind(BeginCallName); DeclarationMatcher InitDeclMatcher = @@ -127,7 +128,8 @@ StatementMatcher makeIteratorLoopMatcher varDecl(hasInitializer(anything())).bind(EndVarName); StatementMatcher EndCallMatcher = cxxMemberCallExpr( - argumentCountIs(0), callee(cxxMethodDecl(hasName("end"; + argumentCountIs(0), + callee(cxxMethodDecl(anyOf(hasName("end"), hasName("cend"); StatementMatcher IteratorBoundMatcher = expr(anyOf(ignoringParenImpCasts( @@ -296,7 +298,8 @@ static const Expr *getContainerFromBegin return nullptr; StringRef Name = Member->getMemberDecl()->getName(); StringRef TargetName = IsBegin ? "begin" : "end"; - if (Name != TargetName) + StringRef ConstTargetName = IsBegin ? "cbegin" : "cend"; + if (Name != TargetName && Name != ConstTargetName) return nullptr; const Expr *SourceExpr = Member->getBase(); @@ -423,7 +426,7 @@ void LoopConvertCheck::storeOptions(Clan Options.store(Opts, "MinConfidence", Confs[static_cast(MinConfidence)]); SmallVector Styles{"camelBack", "CamelCase", "lower_case", -"UPPER_CASE"}; + "UPPER_CASE"}; Options.store(Opts, "NamingStyle", Styles[static_cast(NamingStyle)]); } Modified: clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h?rev=248994&r1=248993&r2=248994&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h (original) +++ clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h Thu Oct 1 03:57:11 2015 @@ -16,11 +16,20 @@ struct MutableVal { int X; }; +struct NonTriviallyCopyable { + NonTriviallyCopyable() = default; + // Define this constructor to make this class non-trivially copyable. + NonTriviallyCopyable(const NonTriviallyCopyable& Ntc); + int X; +}; + struct S { typedef MutableVal *iterator; typedef const MutableVal *const_iterator; const_iterator begin() const; const_iterator end() const; + const_iterator cbegin() const; + const_iterator cend() const; iterator begin(); iterator end(); }; Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp?rev=248994&r1=248993&r2=248994&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Thu Oct 1 03:57:11 2015 @@ -104,6 +104,14 @@ void constArray() { // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto Elem : ConstArr) // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem, Elem + Elem); + + const NonTriviallyCopyable NonCopy[N]{}; + for (int I = 0; I < N; ++I) { +printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X); + } +
[clang-tools-extra] r249006 - Prevent loop-convert from leaving empty lines after removing an alias declaration.
Author: angelgarcia Date: Thu Oct 1 08:08:21 2015 New Revision: 249006 URL: http://llvm.org/viewvc/llvm-project?rev=249006&view=rev Log: Prevent loop-convert from leaving empty lines after removing an alias declaration. Summary: This fixes https://llvm.org/bugs/show_bug.cgi?id=17716. Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D13342 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=249006&r1=249005&r2=249006&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Thu Oct 1 08:08:21 2015 @@ -442,6 +442,30 @@ void LoopConvertCheck::registerMatchers( Finder->addMatcher(makePseudoArrayLoopMatcher(), this); } +/// \brief Given the range of a single declaration, such as: +/// \code +/// unsigned &ThisIsADeclarationThatCanSpanSeveralLinesOfCode = +/// InitializationValues[I]; +/// next_instruction; +/// \endcode +/// Finds the range that has to be erased to remove this declaration without +/// leaving empty lines, by extending the range until the beginning of the +/// next instruction. +/// +/// We need to delete a potential newline after the deleted alias, as +/// clang-format will leave empty lines untouched. For all other formatting we +/// rely on clang-format to fix it. +void LoopConvertCheck::getAliasRange(SourceManager &SM, SourceRange &Range) { + bool Invalid = false; + const char *TextAfter = + SM.getCharacterData(Range.getEnd().getLocWithOffset(1), &Invalid); + if (Invalid) +return; + unsigned Offset = std::strspn(TextAfter, " \t\r\n"); + Range = + SourceRange(Range.getBegin(), Range.getEnd().getLocWithOffset(Offset)); +} + /// \brief Computes the changes needed to convert a given for loop, and /// applies them. void LoopConvertCheck::doConversion( @@ -460,7 +484,7 @@ void LoopConvertCheck::doConversion( AliasVarIsRef = AliasVar->getType()->isReferenceType(); // We keep along the entire DeclStmt to keep the correct range here. -const SourceRange &ReplaceRange = AliasDecl->getSourceRange(); +SourceRange ReplaceRange = AliasDecl->getSourceRange(); std::string ReplacementText; if (AliasUseRequired) { @@ -470,6 +494,9 @@ void LoopConvertCheck::doConversion( // in a for loop's init clause. Need to put this ';' back while removing // the declaration of the alias variable. This is probably a bug. ReplacementText = ";"; +} else { + // Avoid leaving empty lines or trailing whitespaces. + getAliasRange(Context->getSourceManager(), ReplaceRange); } Diag << FixItHint::CreateReplacement( Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h?rev=249006&r1=249005&r2=249006&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h Thu Oct 1 08:08:21 2015 @@ -34,6 +34,8 @@ private: std::string ContainerString; }; + void getAliasRange(SourceManager &SM, SourceRange &DeclRange); + void doConversion(ASTContext *Context, const VarDecl *IndexVar, const VarDecl *MaybeContainer, const UsageResult &Usages, const DeclStmt *AliasDecl, bool AliasUseRequired, Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp?rev=249006&r1=249005&r2=249006&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Thu Oct 1 08:08:21 2015 @@ -53,7 +53,7 @@ void aliasing() { // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & T : Arr) // CHECK-FIXES-NOT: Val &{{[a-z_]+}} = - // CHECK-FIXES: {} + // CHECK-FIXES-NEXT: {} // CHECK-FIXES-NEXT: int Y = T.X; // The container was not only used to initialize a temporary loop variable for @@ -89,7 +89,7 @@ void aliasing() { } // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES:
[clang-tools-extra] r249017 - Update clang-tidy documentation.
Author: angelgarcia Date: Thu Oct 1 09:50:40 2015 New Revision: 249017 URL: http://llvm.org/viewvc/llvm-project?rev=249017&view=rev Log: Update clang-tidy documentation. Summary: Improve modernize-use-auto documentation (https://llvm.org/bugs/show_bug.cgi?id=24962). Add documentation for modernize-make-unique. Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D13346 Added: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=249017&r1=249016&r2=249017&view=diff == --- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Thu Oct 1 09:50:40 2015 @@ -42,6 +42,7 @@ List of clang-tidy Checks misc-unused-parameters misc-unused-raii modernize-loop-convert + modernize-make-unique modernize-pass-by-value modernize-replace-auto-ptr modernize-shrink-to-fit Added: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst?rev=249017&view=auto == --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst (added) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst Thu Oct 1 09:50:40 2015 @@ -0,0 +1,15 @@ +modernize-make-unique += + +This check finds the creation of ``std::unique_ptr`` objects by explicitly +calling the constructor and a ``new`` expression, and replaces it with a call +to ``std::make_unique``, introduced in C++14. + +.. code-block:: c++ + + auto my_ptr = std::unique_ptr(new MyPair(1, 2)); + + // becomes + + auto my_ptr = std::make_unique(1, 2); + Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst?rev=249017&r1=249016&r2=249017&view=diff == --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst (original) +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst Thu Oct 1 09:50:40 2015 @@ -108,6 +108,39 @@ conditions are satisfied: list. Otherwise, use of ``auto`` would cause the type of the variable to be deduced as``std::initializer_list``. +New expressions +--- + +Frequently, when a pointer is declared and initialized with ``new``, the +pointee type has to be written twice: in the declaration type and in the +``new`` expression. In this cases, the declaration type can be replaced with +``auto`` improving readability and maintainability. + +.. code-block:: c++ + + TypeName *my_pointer = new TypeName(my_param); + + // becomes + + auto my_pointer = new TypeName(my_param); + +The check will also replace the declaration type in multiple declarations, if +the following conditions are satisfied: + +* All declared variables have the same type (i.e. all of them are pointers to + the same type). +* All declared variables are initialized with a ``new`` expression. +* The types of all the new expressions are the same than the pointee of the + declaration type. + +.. code-block:: c++ + + TypeName *my_first_pointer = new TypeName, *my_second_pointer = new TypeName; + + // becomes + + auto my_first_pointer = new TypeName, my_second_pointer = new TypeName; + Known Limitations - * If the initializer is an explicit conversion constructor, the check will not ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r249127 - Handle trailing underscores on modernize-loop-convert variable namer.
Author: angelgarcia Date: Fri Oct 2 08:20:11 2015 New Revision: 249127 URL: http://llvm.org/viewvc/llvm-project?rev=249127&view=rev Log: Handle trailing underscores on modernize-loop-convert variable namer. Summary: https://llvm.org/bugs/show_bug.cgi?id=24961. Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D13381 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-lowercase.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-uppercase.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=249127&r1=249126&r2=249127&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Fri Oct 2 08:20:11 2015 @@ -819,6 +819,14 @@ std::string VariableNamer::createIndexNa size_t Len = ContainerName.size(); if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) { IteratorName = ContainerName.substr(0, Len - 1); +// E.g.: (auto thing : things) +if (!declarationExists(IteratorName)) + return IteratorName; + } + + if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) { +IteratorName = ContainerName.substr(0, Len - 2); +// E.g.: (auto thing : things_) if (!declarationExists(IteratorName)) return IteratorName; } @@ -835,14 +843,17 @@ std::string VariableNamer::createIndexNa case NS_UpperCase: Elem = "ELEM"; } + // E.g.: (auto elem : container) if (!declarationExists(Elem)) return Elem; IteratorName = AppendWithStyle(ContainerName, OldIndex->getName()); + // E.g.: (auto container_i : container) if (!declarationExists(IteratorName)) return IteratorName; IteratorName = AppendWithStyle(ContainerName, Elem); + // E.g.: (auto container_elem : container) if (!declarationExists(IteratorName)) return IteratorName; Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-lowercase.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-lowercase.cpp?rev=249127&r1=249126&r2=249127&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-lowercase.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-lowercase.cpp Fri Oct 2 08:20:11 2015 @@ -7,6 +7,7 @@ const int n = 10; int arr[n]; int nums[n]; +int nums_[n]; void naming() { for (int i = 0; i < n; ++i) { @@ -23,6 +24,13 @@ void naming() { // CHECK-FIXES: for (auto & num : nums) // CHECK-FIXES-NEXT: printf("%d\n", num); + for (int i = 0; i < n; ++i) { +printf("%d\n", nums_[i]); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & num : nums_) + // CHECK-FIXES-NEXT: printf("%d\n", num); + int num = 0; for (int i = 0; i < n; ++i) { printf("%d\n", nums[i] + num); Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-uppercase.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-uppercase.cpp?rev=249127&r1=249126&r2=249127&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-uppercase.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-uppercase.cpp Fri Oct 2 08:20:11 2015 @@ -7,6 +7,7 @@ const int N = 10; int ARR[N]; int NUMS[N]; +int NUMS_[N]; void naming() { for (int I = 0; I < N; ++I) { @@ -23,6 +24,13 @@ void naming() { // CHECK-FIXES: for (auto & NUM : NUMS) // CHECK-FIXES-NEXT: printf("%d\n", NUM); + for (int I = 0; I < N; ++I) { +printf("%d\n", NUMS_[I]); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & NUM : NUMS_) + // CHECK-FIXES-NEXT: printf("%d\n", NUM); + int NUM = 0; for (int I = 0; I < N; ++I) { printf("%d\n", NUMS[I] + NUM); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r249129 - Divide TraverseInitListExpr to a different function for each form.
Author: angelgarcia Date: Fri Oct 2 08:25:51 2015 New Revision: 249129 URL: http://llvm.org/viewvc/llvm-project?rev=249129&view=rev Log: Divide TraverseInitListExpr to a different function for each form. Summary: create TraverseSyntacticInitListExpr and TraverseSemanticInitListExpr. Reviewers: rsmith, klimek Subscribers: klimek, cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D13249 Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=249129&r1=249128&r2=249129&view=diff == --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original) +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Oct 2 08:25:51 2015 @@ -255,6 +255,12 @@ public: /// \returns false if the visitation was terminated early, true otherwise. bool TraverseLambdaBody(LambdaExpr *LE); + /// \brief Recursively visit the syntactic or semantic form of an + /// initialization list. + /// + /// \returns false if the visitation was terminated early, true otherwise. + bool TraverseSynOrSemInitListExpr(InitListExpr *S); + // Methods on Attrs // \brief Visit an attribute. @@ -2056,31 +2062,33 @@ DEF_TRAVERSE_STMT(CXXStaticCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) -// InitListExpr is a tricky one, because we want to do all our work on -// the syntactic form of the listexpr, but this method takes the -// semantic form by default. We can't use the macro helper because it -// calls WalkUp*() on the semantic form, before our code can convert -// to the syntactic form. template -bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) { - InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S; - if (Syn) { -TRY_TO(WalkUpFromInitListExpr(Syn)); +bool RecursiveASTVisitor::TraverseSynOrSemInitListExpr(InitListExpr *S) { + if (S) { +TRY_TO(WalkUpFromInitListExpr(S)); // All we need are the default actions. FIXME: use a helper function. -for (Stmt *SubStmt : Syn->children()) { - TRY_TO(TraverseStmt(SubStmt)); -} - } - InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm(); - if (Sem) { -TRY_TO(WalkUpFromInitListExpr(Sem)); -for (Stmt *SubStmt : Sem->children()) { +for (Stmt *SubStmt : S->children()) { TRY_TO(TraverseStmt(SubStmt)); } } return true; } +// This method is called once for each pair of syntactic and semantic +// InitListExpr, and it traverses the subtrees defined by the two forms. This +// may cause some of the children to be visited twice, if they appear both in +// the syntactic and the semantic form. +// +// There is no guarantee about which form \p S takes when this method is called. +template +bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) { + TRY_TO(TraverseSynOrSemInitListExpr( + S->isSemanticForm() ? S->getSyntacticForm() : S)); + TRY_TO(TraverseSynOrSemInitListExpr( + S->isSemanticForm() ? S : S->getSemanticForm())); + return true; +} + // GenericSelectionExpr is a special case because the types and expressions // are interleaved. We also need to watch out for null types (default // generic associations). ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r249291 - Fix bug in modernize-use-nullptr.
Author: angelgarcia Date: Mon Oct 5 03:40:13 2015 New Revision: 249291 URL: http://llvm.org/viewvc/llvm-project?rev=249291&view=rev Log: Fix bug in modernize-use-nullptr. Summary: https://llvm.org/bugs/show_bug.cgi?id=24960 modernize-use-nullptr would hit an assertion in some cases involving macros and initializer lists, due to finding a node with more than one parent (the two forms of the initializer list). However, this doesn't mean that the replacement is incorrect, so instead of just rejecting this case I tried to find a way to make it work. Looking at the semantic form of the InitListExpr made sense to me (looking at both forms results in false negatives) but I am not sure of the things that we can miss by skipping the syntactic form. Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D13246 Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp?rev=249291&r1=249290&r2=249291&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp Mon Oct 5 03:40:13 2015 @@ -150,6 +150,16 @@ public: return true; } + bool TraverseInitListExpr(InitListExpr *S) { +// Only go through the semantic form of the InitListExpr, because +// ImplicitCast might not appear in the syntactic form, and this results in +// finding usages of the macro argument that don't have a ImplicitCast as an +// ancestor (thus invalidating the replacement) when they actually have. +return RecursiveASTVisitor:: +TraverseSynOrSemInitListExpr( +S->isSemanticForm() ? S : S->getSemanticForm()); + } + bool foundInvalid() const { return InvalidFound; } private: @@ -273,7 +283,7 @@ private: // Visit children of this containing parent looking for the least-descended // nodes of the containing parent which are macro arg expansions that expand // from the given arg location. -// Visitor needs: arg loc +// Visitor needs: arg loc. MacroArgUsageVisitor ArgUsageVisitor(SM.getFileLoc(CastLoc), SM); if (const auto *D = ContainingAncestor.get()) ArgUsageVisitor.TraverseDecl(const_cast(D)); @@ -345,8 +355,8 @@ private: /// also handled. /// /// False means either: - /// - TestLoc is not from a macro expansion - /// - TestLoc is from a different macro expansion + /// - TestLoc is not from a macro expansion. + /// - TestLoc is from a different macro expansion. bool expandsFrom(SourceLocation TestLoc, SourceLocation TestMacroLoc) { if (TestLoc.isFileID()) { return false; @@ -399,8 +409,7 @@ private: ast_type_traits::DynTypedNode &Result) { // Below we're only following the first parent back up the AST. This should // be fine since for the statements we care about there should only be one -// parent as far up as we care. If this assumption doesn't hold, need to -// revisit what to do here. +// parent, except for the case specified below. assert(MacroLoc.isFileID()); @@ -408,8 +417,16 @@ private: const auto &Parents = Context.getParents(Start); if (Parents.empty()) return false; - assert(Parents.size() == 1 && - "Found an ancestor with more than one parent!"); + if (Parents.size() > 1) { +// If there are more than one parents, don't do the replacement unless +// they are InitListsExpr (semantic and syntactic form). In this case we +// can choose any one here, and the ASTVisitor will take care of +// traversing the right one. +for (const auto &Parent : Parents) { + if (!Parent.get()) +return false; +} + } const ast_type_traits::DynTypedNode &Parent = Parents[0]; Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp?rev=249291&r1=249290&r2=249291&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp Mon Oct 5 03:40:13 2015 @@ -174,4 +174,13 @@ void test_macro_args() { #define CALL(X) X OPTIONAL_CODE(NOT_NULL); CALL(NOT_NULL); + +#define ENTRY(X) {X} + struct A { +int *Ptr; + } a[2] = {ENTRY(0), {0}}; + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr + // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use nullptr +
[clang-tools-extra] r249300 - Document a bug in loop-convert and fix one of its subcases.
Author: angelgarcia Date: Mon Oct 5 06:15:39 2015 New Revision: 249300 URL: http://llvm.org/viewvc/llvm-project?rev=249300&view=rev Log: Document a bug in loop-convert and fix one of its subcases. Summary: Now that we prioritize copying trivial types over using const-references where possible, I found some cases where, after the transformation, the loop was using the address of the local copy instead of the original object. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13431 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=249300&r1=249299&r2=249300&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Mon Oct 5 06:15:39 2015 @@ -477,6 +477,7 @@ void LoopConvertCheck::doConversion( std::string VarName; bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl; bool AliasVarIsRef = false; + bool CanCopy = true; if (VarNameFromAlias) { const auto *AliasVar = cast(AliasDecl->getSingleDecl()); @@ -525,6 +526,16 @@ void LoopConvertCheck::doConversion( // and parenthesis around a simple DeclRefExpr can always be // removed. Range = Paren->getSourceRange(); + } else if (const auto *UOP = Parents[0].get()) { +// If we are taking the address of the loop variable, then we must +// not use a copy, as it would mean taking the address of the loop's +// local index instead. +// FIXME: This won't catch cases where the address is taken outside +// of the loop's body (for instance, in a function that got the +// loop's index as a const reference parameter), or where we take +// the address of a member (like "&Arr[i].A.B.C"). +if (UOP->getOpcode() == UO_AddrOf) + CanCopy = false; } } } else { @@ -548,8 +559,10 @@ void LoopConvertCheck::doConversion( // If the new variable name is from the aliased variable, then the reference // type for the new variable should only be used if the aliased variable was // declared as a reference. - bool UseCopy = (VarNameFromAlias && !AliasVarIsRef) || - (Descriptor.DerefByConstRef && Descriptor.IsTriviallyCopyable); + bool UseCopy = + CanCopy && + ((VarNameFromAlias && !AliasVarIsRef) || + (Descriptor.DerefByConstRef && Descriptor.IsTriviallyCopyable)); if (!UseCopy) { if (Descriptor.DerefByConstRef) { Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp?rev=249300&r1=249299&r2=249300&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Mon Oct 5 06:15:39 2015 @@ -97,7 +97,7 @@ void f() { // CHECK-FIXES-NEXT: Tea.g(); } -void constArray() { +const int *constArray() { for (int I = 0; I < N; ++I) { printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]); } @@ -112,6 +112,16 @@ void constArray() { // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (const auto & Elem : NonCopy) // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", Elem.X, Elem.X + Elem.X); + + bool Something = false; + for (int I = 0; I < N; ++I) { +if (Something) + return &ConstArr[I]; + } + // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (const auto & Elem : ConstArr) + // CHECK-FIXES-NEXT: if (Something) + // CHECK-FIXES-NEXT: return &Elem; } struct HasArr { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r249305 - Use better mocks in modernize-make-unique, and fix matcher.
Author: angelgarcia Date: Mon Oct 5 07:20:17 2015 New Revision: 249305 URL: http://llvm.org/viewvc/llvm-project?rev=249305&view=rev Log: Use better mocks in modernize-make-unique, and fix matcher. Summary: Add the second template argument to the unique_ptr mock, and update the matcher so that it only matches against cases where the second argument is the default. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13433 Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp?rev=249305&r1=249304&r2=249305&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp Mon Oct 5 07:20:17 2015 @@ -29,10 +29,18 @@ void MakeUniqueCheck::registerMatchers(M cxxConstructExpr( hasType(qualType(hasDeclaration(classTemplateSpecializationDecl( matchesName("::std::unique_ptr"), -templateArgumentCountIs(1), +templateArgumentCountIs(2), +hasTemplateArgument(0, templateArgument(refersToType( + qualType().bind(PointerType, hasTemplateArgument( -0, templateArgument( - refersToType(qualType().bind(PointerType, +1, templateArgument(refersToType(qualType( + hasDeclaration(classTemplateSpecializationDecl( + matchesName("::std::default_delete"), + templateArgumentCountIs(1), + hasTemplateArgument( + 0, templateArgument(refersToType( + qualType(equalsBoundNode( + PointerType))), argumentCountIs(1), hasArgument(0, cxxNewExpr(hasType(pointsTo(qualType( equalsBoundNode(PointerType) Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp?rev=249305&r1=249304&r2=249305&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Mon Oct 5 07:20:17 2015 @@ -2,7 +2,10 @@ namespace std { -template +template +class default_delete {}; + +template > class unique_ptr { public: unique_ptr(type *ptr); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r249402 - Create interfaces and tests for the overlapping replacements fix in clang-tidy.
Author: angelgarcia Date: Tue Oct 6 08:52:51 2015 New Revision: 249402 URL: http://llvm.org/viewvc/llvm-project?rev=249402&view=rev Log: Create interfaces and tests for the overlapping replacements fix in clang-tidy. Summary: No changes in clang-tidy yet. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13469 Added: clang-tools-extra/trunk/unittests/clang-tidy/OverlappingReplacementsTest.cpp Modified: clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h clang-tools-extra/trunk/unittests/clang-tidy/ReadabilityModuleTest.cpp Modified: clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt?rev=249402&r1=249401&r2=249402&view=diff == --- clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt (original) +++ clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt Tue Oct 6 08:52:51 2015 @@ -13,6 +13,7 @@ add_extra_unittest(ClangTidyTests GoogleModuleTest.cpp LLVMModuleTest.cpp MiscModuleTest.cpp + OverlappingReplacementsTest.cpp ReadabilityModuleTest.cpp) target_link_libraries(ClangTidyTests Modified: clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h?rev=249402&r1=249401&r2=249402&view=diff == --- clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h (original) +++ clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h Tue Oct 6 08:52:51 2015 @@ -18,6 +18,7 @@ #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/Tooling.h" #include +#include namespace clang { namespace tidy { @@ -25,9 +26,10 @@ namespace test { class TestClangTidyAction : public ASTFrontendAction { public: - TestClangTidyAction(ClangTidyCheck &Check, ast_matchers::MatchFinder &Finder, + TestClangTidyAction(SmallVectorImpl> &Checks, + ast_matchers::MatchFinder &Finder, ClangTidyContext &Context) - : Check(Check), Finder(Finder), Context(Context) {} + : Checks(Checks), Finder(Finder), Context(Context) {} private: std::unique_ptr CreateASTConsumer(CompilerInstance &Compiler, @@ -36,17 +38,37 @@ private: Context.setCurrentFile(File); Context.setASTContext(&Compiler.getASTContext()); -Check.registerMatchers(&Finder); -Check.registerPPCallbacks(Compiler); +for (auto &Check : Checks) { + Check->registerMatchers(&Finder); + Check->registerPPCallbacks(Compiler); +} return Finder.newASTConsumer(); } - ClangTidyCheck &Check; + SmallVectorImpl> &Checks; ast_matchers::MatchFinder &Finder; ClangTidyContext &Context; }; -template +template struct CheckFactory { + static void + createChecks(ClangTidyContext *Context, + SmallVectorImpl> &Result) { +CheckFactory::createChecks(Context, Result); +CheckFactory::createChecks(Context, Result); + } +}; + +template struct CheckFactory { + static void + createChecks(ClangTidyContext *Context, + SmallVectorImpl> &Result) { +Result.emplace_back(llvm::make_unique( +"test-check-" + std::to_string(Result.size()), Context)); + } +}; + +template std::string runCheckOnCode(StringRef Code, std::vector *Errors = nullptr, const Twine &Filename = "input.cc", @@ -59,7 +81,6 @@ runCheckOnCode(StringRef Code, std::vect ClangTidyContext Context(llvm::make_unique( ClangTidyGlobalOptions(), Options)); ClangTidyDiagnosticConsumer DiagConsumer(Context); - T Check("test-check", &Context); std::vector ArgCXX11(1, "clang-tidy"); ArgCXX11.push_back("-fsyntax-only"); @@ -71,8 +92,11 @@ runCheckOnCode(StringRef Code, std::vect ast_matchers::MatchFinder Finder; llvm::IntrusiveRefCntPtr Files( new FileManager(FileSystemOptions())); + + SmallVector, 1> Checks; + CheckFactory::createChecks(&Context, Checks); tooling::ToolInvocation Invocation( - ArgCXX11, new TestClangTidyAction(Check, Finder, Context), Files.get()); + ArgCXX11, new TestClangTidyAction(Checks, Finder, Context), Files.get()); Invocation.mapVirtualFile(Filename.str(), Code); for (const auto &FileContent : PathsToContent) { Invocation.mapVirtualFile(Twine("include/" + FileContent.first).str(), Added: clang-tools-extra/trunk/unittests/clang-tidy/OverlappingReplacementsTest.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/OverlappingReplacementsTest.cpp?rev=249402&view=auto == --- clang-tools-extra/trunk/unittests/clang-tidy/OverlappingReplacement
[clang-tools-extra] r245701 - Test commit!
Author: angelgarcia Date: Fri Aug 21 08:55:16 2015 New Revision: 245701 URL: http://llvm.org/viewvc/llvm-project?rev=245701&view=rev Log: Test commit! Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp?rev=245701&r1=245700&r2=245701&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp Fri Aug 21 08:55:16 2015 @@ -439,6 +439,7 @@ private: Expr *FirstSubExpr; bool PruneSubtree; }; + } // namespace UseNullptrCheck::UseNullptrCheck(StringRef Name, ClangTidyContext *Context) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r245703 - [clang-tidy] Migrate UseAuto from clang-modernize to clang-tidy.
Author: angelgarcia Date: Fri Aug 21 10:08:51 2015 New Revision: 245703 URL: http://llvm.org/viewvc/llvm-project?rev=245703&view=rev Log: [clang-tidy] Migrate UseAuto from clang-modernize to clang-tidy. http://reviews.llvm.org/D12231 Added: clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.h clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-use-auto/ clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-use-auto/containers.h clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-iterator.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt?rev=245703&r1=245702&r2=245703&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Fri Aug 21 10:08:51 2015 @@ -5,6 +5,7 @@ add_clang_library(clangTidyModernizeModu LoopConvertUtils.cpp ModernizeTidyModule.cpp PassByValueCheck.cpp + UseAutoCheck.cpp UseNullptrCheck.cpp LINK_LIBS Modified: clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp?rev=245703&r1=245702&r2=245703&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Fri Aug 21 10:08:51 2015 @@ -12,6 +12,7 @@ #include "../ClangTidyModuleRegistry.h" #include "LoopConvertCheck.h" #include "PassByValueCheck.h" +#include "UseAutoCheck.h" #include "UseNullptrCheck.h" using namespace clang::ast_matchers; @@ -25,6 +26,7 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck("modernize-loop-convert"); CheckFactories.registerCheck("modernize-pass-by-value"); +CheckFactories.registerCheck("modernize-use-auto"); CheckFactories.registerCheck("modernize-use-nullptr"); } Added: clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp?rev=245703&view=auto == --- clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp (added) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp Fri Aug 21 10:08:51 2015 @@ -0,0 +1,368 @@ +//===--- UseAutoCheck.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 "UseAutoCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang; +using namespace clang::ast_matchers; +using namespace clang::ast_matchers::internal; + +namespace clang { +namespace tidy { +namespace modernize { +namespace { + +const char IteratorDeclStmtId[] = "iterator_decl"; +const char DeclWithNewId[] = "decl_new"; + +/// \brief Matches variable declarations that have explicit initializers that +/// are not initializer lists. +/// +/// Given +/// \code +/// iterator I = Container.begin(); +/// MyType A(42); +/// MyType B{2}; +/// MyType C; +/// \endcode +/// +/// varDecl(hasWrittenNonListInitializer()) maches \c I and \c A but not \c B +/// or \c C. +AST_MATCHER(VarDecl, hasWrittenNonListInitializer) { + const Expr *Init = Node.getAnyInitializer(); + if (!Init) +return false; + + // The following test is based on DeclPrinter::VisitVarDecl() to find if an + // initializer is implicit or not. + if (const auto *Construct = dyn_cast(Init)) { +return !Construct->isListInitialization() && Construct->getNumArgs() > 0 && + !Construct->getArg(0)->isDefaultArgument(); + } + return Node.getInitStyle() != VarDecl::ListInit; +} + +/// \brief Matches QualTypes that are type sugar for QualTypes that match \c +/// SugarMatcher. +/// +/// Given +/// \code +/// class C {}; +/// typedef C my_type; +/// typedef my_type my_other_type; +/// \endcode +/// +/// qualType(isSugarFor(recordType(hasDeclaration(namedDecl(hasName("C")) +/// matches \c my_type and \c my_other_type. +AST_MATCHER_P(Q
[clang-tools-extra] r245926 - Tests no longer need the 'REQUIRES: SHELL' line.
Author: angelgarcia Date: Tue Aug 25 03:39:34 2015 New Revision: 245926 URL: http://llvm.org/viewvc/llvm-project?rev=245926&view=rev Log: Tests no longer need the 'REQUIRES: SHELL' line. Summary: Update python script, so that it doesn't print that line in new tests. Reviewers: alexfh Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D12281 Modified: clang-tools-extra/trunk/clang-tidy/add_new_check.py Modified: clang-tools-extra/trunk/clang-tidy/add_new_check.py URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/add_new_check.py?rev=245926&r1=245925&r2=245926&view=diff == --- clang-tools-extra/trunk/clang-tidy/add_new_check.py (original) +++ clang-tools-extra/trunk/clang-tidy/add_new_check.py Tue Aug 25 03:39:34 2015 @@ -184,7 +184,6 @@ def write_test(module_path, module, chec with open(filename, 'w') as f: f.write( """// RUN: %%python %%S/check_clang_tidy.py %%s %(check_name_dashes)s %%t -// REQUIRES: shell // FIXME: Add something that triggers the check here. void f(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r245933 - Add replace-auto_ptr check.
Author: angelgarcia Date: Tue Aug 25 08:03:43 2015 New Revision: 245933 URL: http://llvm.org/viewvc/llvm-project?rev=245933&view=rev Log: Add replace-auto_ptr check. Summary: Migrate replace-auto_ptr check from clang-modernize to modernize module in clang-tidy. Reviewers: alexfh Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D12287 Added: clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.h clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-replace-auto-ptr/ clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-replace-auto-ptr/memory.h clang-tools-extra/trunk/test/clang-tidy/modernize-replace-auto-ptr.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt?rev=245933&r1=245932&r2=245933&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Tue Aug 25 08:03:43 2015 @@ -5,6 +5,7 @@ add_clang_library(clangTidyModernizeModu LoopConvertUtils.cpp ModernizeTidyModule.cpp PassByValueCheck.cpp + ReplaceAutoPtrCheck.cpp UseAutoCheck.cpp UseNullptrCheck.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp?rev=245933&r1=245932&r2=245933&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Tue Aug 25 08:03:43 2015 @@ -12,6 +12,7 @@ #include "../ClangTidyModuleRegistry.h" #include "LoopConvertCheck.h" #include "PassByValueCheck.h" +#include "ReplaceAutoPtrCheck.h" #include "UseAutoCheck.h" #include "UseNullptrCheck.h" @@ -26,6 +27,8 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck("modernize-loop-convert"); CheckFactories.registerCheck("modernize-pass-by-value"); +CheckFactories.registerCheck( +"modernize-replace-auto-ptr"); CheckFactories.registerCheck("modernize-use-auto"); CheckFactories.registerCheck("modernize-use-nullptr"); } @@ -35,6 +38,7 @@ public: auto &Opts = Options.CheckOptions; Opts["modernize-loop-convert.MinConfidence"] = "reasonable"; Opts["modernize-pass-by-value.IncludeStyle"] = "llvm"; // Also: "google". +Opts["modernize-replace-auto-ptr.IncludeStyle"] = "llvm"; // Also: "google". // Comma-separated list of macros that behave like NULL. Opts["modernize-use-nullptr.NullMacros"] = "NULL"; Added: clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp?rev=245933&view=auto == --- clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp (added) +++ clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp Tue Aug 25 08:03:43 2015 @@ -0,0 +1,262 @@ +//===--- ReplaceAutoPtrCheck.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 "ReplaceAutoPtrCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" + +using namespace clang; +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace modernize { + +const char AutoPtrTokenId[] = "AutoPrTokenId"; +const char AutoPtrOwnershipTransferId[] = "AutoPtrOwnershipTransferId"; + +/// \brief Matches expressions that are lvalues. +/// +/// In the following example, a[0] matches expr(isLValue()): +/// \code +/// std::string a[2]; +/// std::string b; +/// b = a[0]; +/// b = "this string won't match"; +/// \endcode +AST_MATCHER(Expr, isLValue) { return Node.getValueKind() == VK_LValue; } + +/// Matches declarations whose declaration context is the C++ standard library +/// namespace std. +/// +/// Note that inline namespaces are silently ignored during the lookup since +/// both libstdc++ and libc++ are known to use them fo
[clang-tools-extra] r245942 - Avoid LoopConvertCheck replacements in template instantiations.
Author: angelgarcia Date: Tue Aug 25 10:44:00 2015 New Revision: 245942 URL: http://llvm.org/viewvc/llvm-project?rev=245942&view=rev Log: Avoid LoopConvertCheck replacements in template instantiations. Summary: Prevent LoopConvertCheck from doing replacements in template instantiations, and add a test. Reviewers: alexfh Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D12321 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=245942&r1=245941&r2=245942&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Tue Aug 25 10:44:00 2015 @@ -70,6 +70,7 @@ StatementMatcher makeArrayLoopMatcher() expr(hasType(isInteger())).bind(ConditionBoundName); return forStmt( + unless(isInTemplateInstantiation()), hasLoopInit(declStmt(hasSingleDecl(InitToZeroMatcher))), hasCondition(anyOf( binaryOperator(hasOperatorName("<"), @@ -159,6 +160,7 @@ StatementMatcher makeIteratorLoopMatcher .bind(DerefByRefResultName))); return forStmt( + unless(isInTemplateInstantiation()), hasLoopInit(anyOf(declStmt(declCountIs(2), containsDeclaration(0, InitDeclMatcher), containsDeclaration(1, EndDeclMatcher)), @@ -258,6 +260,7 @@ StatementMatcher makePseudoArrayLoopMatc EndInitMatcher)); return forStmt( + unless(isInTemplateInstantiation()), hasLoopInit( anyOf(declStmt(declCountIs(2), containsDeclaration(0, InitToZeroMatcher), Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp?rev=245942&r1=245941&r2=245942&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Tue Aug 25 10:44:00 2015 @@ -626,3 +626,24 @@ void messing_with_macros() { } } // namespace Macros + +namespace Templates { + +template +void set_union(Container &container) { + for (typename Container::const_iterator SI = container.begin(), + SE = container.end(); SI != SE; ++SI) { + } + S s; + for (S::iterator SI = s.begin(), SE = s.end(); SI != SE; ++SI) { + } + // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & elem : s) { +} + +void template_instantiation() { + S a; + set_union(a); +} + +} // namespace Templates ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r246034 - LoopConvert no longer take as alias references to other containers.
Author: angelgarcia Date: Wed Aug 26 09:51:11 2015 New Revision: 246034 URL: http://llvm.org/viewvc/llvm-project?rev=246034&view=rev Log: LoopConvert no longer take as alias references to other containers. Summary: Fix a bug where modernize-loop-convert check would take as alias a reference to other containers. Add the pertinent test. Reviewers: alexfh Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D12361 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=246034&r1=246033&r2=246034&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Wed Aug 26 09:51:11 2015 @@ -363,7 +363,7 @@ static bool isAliasDecl(const Decl *TheD return isDereferenceOfOpCall(OpCall, IndexVar); if (OpCall->getOperator() == OO_Subscript) { assert(OpCall->getNumArgs() == 2); - return true; + return isIndexInSubscriptExpr(OpCall->getArg(1), IndexVar); } break; } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp?rev=246034&r1=246033&r2=246034&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Wed Aug 26 09:51:11 2015 @@ -202,6 +202,16 @@ void refs_and_vals() { // CHECK-FIXES-NOT: MutableVal &{{[a-z_]+}} = // CHECK-FIXES: {} // CHECK-FIXES-NEXT: alias.x = 0; + + dependent dep, other; + for (dependent::iterator it = dep.begin(), e = dep.end(); it != e; ++it) { +printf("%d\n", *it); +const int& idx = other[0]; + } + // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & elem : dep) + // CHECK-FIXES-NEXT: printf("%d\n", elem); + // CHECK-FIXES-NEXT: const int& idx = other[0]; } } // namespace NamingAlias ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r246039 - Fix another LoopConvert fail.
Author: angelgarcia Date: Wed Aug 26 12:08:24 2015 New Revision: 246039 URL: http://llvm.org/viewvc/llvm-project?rev=246039&view=rev Log: Fix another LoopConvert fail. Summary: Prevent LoopConvert from taking as alias anything that comes from a random member function call. Reviewers: alexfh Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D12370 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=246039&r1=246038&r2=246039&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Wed Aug 26 12:08:24 2015 @@ -368,8 +368,14 @@ static bool isAliasDecl(const Decl *TheD break; } - case Stmt::CXXMemberCallExprClass: -return true; + case Stmt::CXXMemberCallExprClass: { +const auto *MemCall = cast(Init); +if (MemCall->getMethodDecl()->getName() == "at") { + assert(MemCall->getNumArgs() == 1); + return isIndexInSubscriptExpr(MemCall->getArg(0), IndexVar); +} +return false; + } default: break; Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp?rev=246039&r1=246038&r2=246039&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Wed Aug 26 12:08:24 2015 @@ -207,11 +207,17 @@ void refs_and_vals() { for (dependent::iterator it = dep.begin(), e = dep.end(); it != e; ++it) { printf("%d\n", *it); const int& idx = other[0]; +unsigned othersize = other.size(); } - // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead + // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : dep) // CHECK-FIXES-NEXT: printf("%d\n", elem); // CHECK-FIXES-NEXT: const int& idx = other[0]; + // CHECK-FIXES-NEXT: unsigned othersize = other.size(); + + for (int i = 0, e = dep.size(); i != e; ++i) { +int idx = other.at(i); + } } } // namespace NamingAlias ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r246550 - Fix several corner cases for loop-convert check.
Author: angelgarcia Date: Tue Sep 1 10:05:15 2015 New Revision: 246550 URL: http://llvm.org/viewvc/llvm-project?rev=246550&view=rev Log: Fix several corner cases for loop-convert check. Summary: Reduced the amount of wrong conversions of this check. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D12530 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-negative.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=246550&r1=246549&r2=246550&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Tue Sep 1 10:05:15 2015 @@ -364,6 +364,23 @@ static bool isDirectMemberExpr(const Exp return false; } +/// \brief Returns true when it can be guaranteed that the elements of the +/// container are not being modified. +static bool usagesAreConst(const UsageResult &Usages) { + // FIXME: Make this function more generic. + return Usages.empty(); +} + +/// \brief Returns true if the elements of the container are never accessed +/// by reference. +static bool usagesReturnRValues(const UsageResult &Usages) { + for (const auto &U : Usages) { +if (!U.Expression->isRValue()) + return false; + } + return true; +} + LoopConvertCheck::LoopConvertCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), TUInfo(new TUTrackingInfo), MinConfidence(StringSwitch( @@ -452,7 +469,8 @@ void LoopConvertCheck::doConversion( StringRef MaybeDereference = ContainerNeedsDereference ? "*" : ""; std::string TypeString = AutoRefType.getAsString(); std::string Range = ("(" + TypeString + " " + VarName + " : " + - MaybeDereference + ContainerString + ")").str(); + MaybeDereference + ContainerString + ")") + .str(); Diag << FixItHint::CreateReplacement( CharSourceRange::getTokenRange(ParenRange), Range); TUInfo->getGeneratedDecls().insert(make_pair(TheLoop, VarName)); @@ -464,7 +482,7 @@ void LoopConvertCheck::doConversion( StringRef LoopConvertCheck::checkRejections(ASTContext *Context, const Expr *ContainerExpr, const ForStmt *TheLoop) { - // If we already modified the reange of this for loop, don't do any further + // If we already modified the range of this for loop, don't do any further // updates on this iteration. if (TUInfo->getReplacedVars().count(TheLoop)) return ""; @@ -525,6 +543,18 @@ void LoopConvertCheck::findAndVerifyUsag if (!getReferencedVariable(ContainerExpr) && !isDirectMemberExpr(ContainerExpr)) ConfidenceLevel.lowerTo(Confidence::CL_Risky); + } else if (FixerKind == LFK_PseudoArray) { +if (!DerefByValue && !DerefByConstRef) { + const UsageResult &Usages = Finder.getUsages(); + if (usagesAreConst(Usages)) { +// FIXME: check if the type is trivially copiable. +DerefByConstRef = true; + } else if (usagesReturnRValues(Usages)) { +// If the index usages (dereference, subscript, at) return RValues, +// then we should not use a non-const reference. +DerefByValue = true; + } +} } StringRef ContainerString = checkRejections(Context, ContainerExpr, TheLoop); Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=246550&r1=246549&r2=246550&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Tue Sep 1 10:05:15 2015 @@ -425,12 +425,8 @@ ForLoopIndexUseVisitor::ForLoopIndexUseV ConfidenceLevel(Confidence::CL_Safe), NextStmtParent(nullptr), CurrStmtParent(nullptr), ReplaceWithAliasUse(false), AliasFromForInit(false) { - if (ContainerExpr) { + if (ContainerExpr) addComponent(ContainerExpr); -FoldingSetNodeID ID; -const Expr *E = ContainerExpr->IgnoreParenImpCasts(); -E->Profile(ID, *Context, true); - } } bool ForLoopIndexUseVisitor::findAndVerifyUsages(const Stmt *Body) { @@ -521,
[clang-tools-extra] r246638 - Fix use-auto-check.
Author: angelgarcia Date: Wed Sep 2 05:20:00 2015 New Revision: 246638 URL: http://llvm.org/viewvc/llvm-project?rev=246638&view=rev Log: Fix use-auto-check. Summary: Fix a bug where use-auto check would crash when the definition of a type is in the same statement than its instantiation with new. Reviewers: alexfh Subscribers: cfe-commits, klimek Differential Revision: http://reviews.llvm.org/D12551 Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp?rev=246638&r1=246637&r2=246638&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp Wed Sep 2 05:20:00 2015 @@ -298,7 +298,7 @@ void UseAutoCheck::replaceIterators(cons } void UseAutoCheck::replaceNew(const DeclStmt *D, ASTContext *Context) { - const auto *FirstDecl = cast(*D->decl_begin()); + const auto *FirstDecl = dyn_cast(*D->decl_begin()); // Ensure that there is at least one VarDecl within the DeclStmt. if (!FirstDecl) return; Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp?rev=246638&r1=246637&r2=246638&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp Wed Sep 2 05:20:00 2015 @@ -37,6 +37,8 @@ void auto_new() { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new // CHECK-FIXES: auto volatile vol = new MyType(); + struct SType {} *stype = new SType; + int (**func)(int, int) = new (int(*[5])(int,int)); int *array = new int[5]; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r246655 - Fix loop-convert crash.
Author: angelgarcia Date: Wed Sep 2 09:25:08 2015 New Revision: 246655 URL: http://llvm.org/viewvc/llvm-project?rev=246655&view=rev Log: Fix loop-convert crash. Summary: loop-convert no longer crashes when calling a member function using a member pointer which is a member of another record. Reviewers: alexfh, klimek Subscribers: cfe-commits, klimek Differential Revision: http://reviews.llvm.org/D12555 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=246655&r1=246654&r2=246655&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Wed Sep 2 09:25:08 2015 @@ -370,7 +370,10 @@ static bool isAliasDecl(const Decl *TheD case Stmt::CXXMemberCallExprClass: { const auto *MemCall = cast(Init); -if (MemCall->getMethodDecl()->getName() == "at") { +// This check is needed because getMethodDecl can return nullptr if the +// callee is a member function pointer. +if (MemCall->getMethodDecl() && +MemCall->getMethodDecl()->getName() == "at") { assert(MemCall->getNumArgs() == 1); return isIndexInSubscriptExpr(MemCall->getArg(0), IndexVar); } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp?rev=246655&r1=246654&r2=246655&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Wed Sep 2 09:25:08 2015 @@ -156,6 +156,17 @@ void memberFunctionPointer() { // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead // CHECK-FIXES: for (auto & elem : mfpArr) // CHECK-FIXES-NEXT: (v.*elem)(); + + struct Foo { +int (Val::*f)(); + } foo[N]; + + for (int i = 0; i < N; ++i) +int r = (v.*(foo[i].f))(); + // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & elem : foo) + // CHECK-FIXES-NEXT: int r = (v.*(elem.f))(); + } } // namespace Array ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r246762 - Two more fixes to loop convert.
Author: angelgarcia Date: Thu Sep 3 07:28:11 2015 New Revision: 246762 URL: http://llvm.org/viewvc/llvm-project?rev=246762&view=rev Log: Two more fixes to loop convert. Summary: Ensure that the alias has the same type than the loop variable. Now it works with lambda captures. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D12597 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=246762&r1=246761&r2=246762&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Thu Sep 3 07:28:11 2015 @@ -334,7 +334,8 @@ static bool isDereferenceOfUop(const Una /// // use t, do not use i /// } /// \endcode -static bool isAliasDecl(const Decl *TheDecl, const VarDecl *IndexVar) { +static bool isAliasDecl(ASTContext *Context, const Decl *TheDecl, +const VarDecl *IndexVar) { const auto *VDecl = dyn_cast(TheDecl); if (!VDecl) return false; @@ -346,6 +347,15 @@ static bool isAliasDecl(const Decl *TheD if (!Init) return false; + // Check that the declared type is the same as (or a reference to) the + // container type. + QualType DeclarationType = VDecl->getType(); + if (DeclarationType->isReferenceType()) +DeclarationType = DeclarationType.getNonReferenceType(); + QualType InitType = Init->getType(); + if (!Context->hasSameUnqualifiedType(DeclarationType, InitType)) +return false; + switch (Init->getStmtClass()) { case Stmt::ArraySubscriptExprClass: { const auto *E = cast(Init); @@ -711,13 +721,49 @@ bool ForLoopIndexUseVisitor::VisitDeclRe return true; } +/// \brief If the loop index is captured by a lambda, replace this capture +/// by the range-for loop variable. +/// +/// For example: +/// \code +/// for (int i = 0; i < N; ++i) { +/// auto f = [v, i](int k) { +/// printf("%d\n", v[i] + k); +/// }; +/// f(v[i]); +/// } +/// \endcode +/// +/// Will be replaced by: +/// \code +/// for (auto & elem : v) { +/// auto f = [v, elem](int k) { +/// printf("%d\n", elem + k); +/// }; +/// f(elem); +/// } +/// \endcode +bool ForLoopIndexUseVisitor::TraverseLambdaCapture(LambdaExpr *LE, + const LambdaCapture *C) { + if (C->capturesVariable()) { +const VarDecl* VDecl = C->getCapturedVar(); +if (areSameVariable(IndexVar, cast(VDecl))) { + // FIXME: if the index is captured, it will count as an usage and the + // alias (if any) won't work, because it is only used in case of having + // exactly one usage. + Usages.push_back(Usage(nullptr, false, C->getLocation())); +} + } + return VisitorBase::TraverseLambdaCapture(LE, C); +} + /// \brief If we find that another variable is created just to refer to the loop /// element, note it for reuse as the loop variable. /// /// See the comments for isAliasDecl. bool ForLoopIndexUseVisitor::VisitDeclStmt(DeclStmt *S) { if (!AliasDecl && S->isSingleDecl() && - isAliasDecl(S->getSingleDecl(), IndexVar)) { + isAliasDecl(Context, S->getSingleDecl(), IndexVar)) { AliasDecl = S; if (CurrStmtParent) { if (isa(CurrStmtParent) || isa(CurrStmtParent) || Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h?rev=246762&r1=246761&r2=246762&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h Thu Sep 3 07:28:11 2015 @@ -309,6 +309,7 @@ private: bool TraverseArraySubscriptExpr(ArraySubscriptExpr *E); bool TraverseCXXMemberCallExpr(CXXMemberCallExpr *MemberCall); bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *OpCall); + bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C); bool TraverseMemberExpr(MemberExpr *Member); bool TraverseUnaryDeref(UnaryOperator *Uop); bool VisitDeclRefExpr(DeclRefExpr *E); Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp?rev=246762&r1=246761&r2=246762&view=diff == --- clang-tools-extra
[clang-tools-extra] r246879 - Avoid repeated replacements on loop-convert check.
Author: angelgarcia Date: Fri Sep 4 16:37:05 2015 New Revision: 246879 URL: http://llvm.org/viewvc/llvm-project?rev=246879&view=rev Log: Avoid repeated replacements on loop-convert check. Summary: The InitListExpr subtree is visited twice, this caused the check to do multiple replacements. Added a set to avoid it. Reviewers: klimek, alexfh Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D12631 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=246879&r1=246878&r2=246879&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Fri Sep 4 16:37:05 2015 @@ -460,6 +460,15 @@ void ForLoopIndexUseVisitor::addComponen DependentExprs.push_back(std::make_pair(Node, ID)); } +void ForLoopIndexUseVisitor::addUsage(const Usage &U) { + SourceLocation Begin = U.Range.getBegin(); + if (Begin.isMacroID()) +Begin = Context->getSourceManager().getSpellingLoc(Begin); + + if (UsageLocations.insert(Begin).second) +Usages.push_back(U); +} + /// \brief If the unary operator is a dereference of IndexVar, include it /// as a valid usage and prune the traversal. /// @@ -475,7 +484,7 @@ bool ForLoopIndexUseVisitor::TraverseUna // If we dereference an iterator that's actually a pointer, count the // occurrence. if (isDereferenceOfUop(Uop, IndexVar)) { -Usages.push_back(Usage(Uop)); +addUsage(Usage(Uop)); return true; } @@ -549,8 +558,8 @@ bool ForLoopIndexUseVisitor::TraverseMem // If something complicated is happening (i.e. the next token isn't an // arrow), give up on making this work. if (!ArrowLoc.isInvalid()) { - Usages.push_back(Usage(ResultExpr, /*IsArrow=*/true, - SourceRange(Base->getExprLoc(), ArrowLoc))); + addUsage(Usage(ResultExpr, /*IsArrow=*/true, + SourceRange(Base->getExprLoc(), ArrowLoc))); return true; } } @@ -579,7 +588,7 @@ bool ForLoopIndexUseVisitor::TraverseCXX if (isIndexInSubscriptExpr(Context, MemberCall->getArg(0), IndexVar, Member->getBase(), ContainerExpr, ContainerNeedsDereference)) { - Usages.push_back(Usage(MemberCall)); + addUsage(Usage(MemberCall)); return true; } } @@ -614,7 +623,7 @@ bool ForLoopIndexUseVisitor::TraverseCXX switch (OpCall->getOperator()) { case OO_Star: if (isDereferenceOfOpCall(OpCall, IndexVar)) { - Usages.push_back(Usage(OpCall)); + addUsage(Usage(OpCall)); return true; } break; @@ -625,7 +634,7 @@ bool ForLoopIndexUseVisitor::TraverseCXX if (isIndexInSubscriptExpr(Context, OpCall->getArg(1), IndexVar, OpCall->getArg(0), ContainerExpr, ContainerNeedsDereference)) { - Usages.push_back(Usage(OpCall)); + addUsage(Usage(OpCall)); return true; } break; @@ -674,7 +683,7 @@ bool ForLoopIndexUseVisitor::TraverseArr if (!ContainerExpr) ContainerExpr = Arr; - Usages.push_back(Usage(E)); + addUsage(Usage(E)); return true; } @@ -746,12 +755,12 @@ bool ForLoopIndexUseVisitor::VisitDeclRe bool ForLoopIndexUseVisitor::TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) { if (C->capturesVariable()) { -const VarDecl* VDecl = C->getCapturedVar(); +const VarDecl *VDecl = C->getCapturedVar(); if (areSameVariable(IndexVar, cast(VDecl))) { // FIXME: if the index is captured, it will count as an usage and the // alias (if any) won't work, because it is only used in case of having // exactly one usage. - Usages.push_back(Usage(nullptr, false, C->getLocation())); + addUsage(Usage(nullptr, false, C->getLocation())); } } return VisitorBase::TraverseLambdaCapture(LE, C); Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h?rev=246879&r1=246878&r2=246879&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h Fri Sep 4 16:37:05 2015 @@ -277,6 +277,9 @@ public: /// \brief Accessor for Usages. const UsageResult &getUsages() const {
[clang-tools-extra] r246989 - Avoid using rvalue references with trivially copyable types.
Author: angelgarcia Date: Tue Sep 8 04:01:21 2015 New Revision: 246989 URL: http://llvm.org/viewvc/llvm-project?rev=246989&view=rev Log: Avoid using rvalue references with trivially copyable types. Summary: When the dereference operator returns a value that is trivially copyable (like a pointer), copy it. After this change, modernize-loop-convert check can be applied to the whole llvm source code without breaking any build or test. Reviewers: alexfh, klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D12675 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=246989&r1=246988&r2=246989&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Tue Sep 8 04:01:21 2015 @@ -375,7 +375,7 @@ static bool usagesAreConst(const UsageRe /// by reference. static bool usagesReturnRValues(const UsageResult &Usages) { for (const auto &U : Usages) { -if (!U.Expression->isRValue()) +if (U.Expression && !U.Expression->isRValue()) return false; } return true; @@ -400,8 +400,7 @@ void LoopConvertCheck::doConversion( ASTContext *Context, const VarDecl *IndexVar, const VarDecl *MaybeContainer, StringRef ContainerString, const UsageResult &Usages, const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit, -const ForStmt *TheLoop, bool ContainerNeedsDereference, bool DerefByValue, -bool DerefByConstRef) { +const ForStmt *TheLoop, RangeDescriptor Descriptor) { auto Diag = diag(TheLoop->getForLoc(), "use range-based for loop instead"); std::string VarName; @@ -457,16 +456,17 @@ void LoopConvertCheck::doConversion( // If an iterator's operator*() returns a 'T&' we can bind that to 'auto&'. // If operator*() returns 'T' we can bind that to 'auto&&' which will deduce // to 'T&&&'. -if (DerefByValue) { - AutoRefType = Context->getRValueReferenceType(AutoRefType); +if (Descriptor.DerefByValue) { + if (!Descriptor.IsTriviallyCopyable) +AutoRefType = Context->getRValueReferenceType(AutoRefType); } else { - if (DerefByConstRef) + if (Descriptor.DerefByConstRef) AutoRefType = Context->getConstType(AutoRefType); AutoRefType = Context->getLValueReferenceType(AutoRefType); } } - StringRef MaybeDereference = ContainerNeedsDereference ? "*" : ""; + StringRef MaybeDereference = Descriptor.ContainerNeedsDereference ? "*" : ""; std::string TypeString = AutoRefType.getAsString(); std::string Range = ("(" + TypeString + " " + VarName + " : " + MaybeDereference + ContainerString + ")") @@ -518,11 +518,11 @@ StringRef LoopConvertCheck::checkRejecti /// of the index variable and convert the loop if possible. void LoopConvertCheck::findAndVerifyUsages( ASTContext *Context, const VarDecl *LoopVar, const VarDecl *EndVar, -const Expr *ContainerExpr, const Expr *BoundExpr, -bool ContainerNeedsDereference, bool DerefByValue, bool DerefByConstRef, -const ForStmt *TheLoop, LoopFixerKind FixerKind) { +const Expr *ContainerExpr, const Expr *BoundExpr, const ForStmt *TheLoop, +LoopFixerKind FixerKind, RangeDescriptor Descriptor) { ForLoopIndexUseVisitor Finder(Context, LoopVar, EndVar, ContainerExpr, -BoundExpr, ContainerNeedsDereference); +BoundExpr, +Descriptor.ContainerNeedsDereference); if (ContainerExpr) { ComponentFinderASTVisitor ComponentFinder; @@ -544,15 +544,28 @@ void LoopConvertCheck::findAndVerifyUsag !isDirectMemberExpr(ContainerExpr)) ConfidenceLevel.lowerTo(Confidence::CL_Risky); } else if (FixerKind == LFK_PseudoArray) { -if (!DerefByValue && !DerefByConstRef) { +if (!Descriptor.DerefByValue && !Descriptor.DerefByConstRef) { const UsageResult &Usages = Finder.getUsages(); if (usagesAreConst(Usages)) { -// FIXME: check if the type is trivially copiable. -DerefByConstRef = true; +Descriptor.DerefByConstRef = true; } else if (usagesReturnRValues(Usages)) { // If the index usages (dereference, subscript, at) return RValues, // then we should not use a non-const reference. -DerefByValue = true; +Descriptor.DerefByValue = true; +// Try to find the type of the elements on the
[clang-tools-extra] r250283 - Support every kind of initialization.
Author: angelgarcia Date: Wed Oct 14 04:22:32 2015 New Revision: 250283 URL: http://llvm.org/viewvc/llvm-project?rev=250283&view=rev Log: Support every kind of initialization. Summary: modernize-make-unique now correctly supports the different kinds of list initialization. Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D13590 Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp?rev=250283&r1=250282&r2=250283&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp Wed Oct 14 04:22:32 2015 @@ -54,8 +54,11 @@ void MakeUniqueCheck::check(const MatchF SourceManager &SM = *Result.SourceManager; const auto *Construct = Result.Nodes.getNodeAs(ConstructorCall); - const auto *New = Result.Nodes.getNodeAs(NewExpression); const auto *Type = Result.Nodes.getNodeAs(PointerType); + const auto *New = Result.Nodes.getNodeAs(NewExpression); + + if (New->getNumPlacementArgs() != 0) +return; SourceLocation ConstructCallStart = Construct->getExprLoc(); @@ -86,6 +89,20 @@ void MakeUniqueCheck::check(const MatchF CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd), "std::make_unique"); + // If the unique_ptr is built with brace enclosed direct initialization, use + // parenthesis instead. + if (Construct->isListInitialization()) { +SourceRange BraceRange = Construct->getParenOrBraceRange(); +Diag << FixItHint::CreateReplacement( +CharSourceRange::getCharRange( +BraceRange.getBegin(), BraceRange.getBegin().getLocWithOffset(1)), +"("); +Diag << FixItHint::CreateReplacement( +CharSourceRange::getCharRange(BraceRange.getEnd(), + BraceRange.getEnd().getLocWithOffset(1)), +")"); + } + SourceLocation NewStart = New->getSourceRange().getBegin(); SourceLocation NewEnd = New->getSourceRange().getEnd(); switch (New->getInitializationStyle()) { @@ -101,9 +118,30 @@ void MakeUniqueCheck::check(const MatchF break; } case CXXNewExpr::ListInit: { -SourceRange InitRange = New->getInitializer()->getSourceRange(); +// Range of the substring that we do not want to remove. +SourceRange InitRange; +if (const auto *NewConstruct = New->getConstructExpr()) { + // Direct initialization with initialization list. + // struct S { S(int x) {} }; + // std::unique_ptr(new S{5}); + // The arguments in the initialization list are going to be forwarded to + // the constructor, so this has to be replaced with: + // struct S { S(int x) {} }; + // std::make_unique(5); + InitRange = SourceRange( + NewConstruct->getParenOrBraceRange().getBegin().getLocWithOffset(1), + NewConstruct->getParenOrBraceRange().getEnd().getLocWithOffset(-1)); +} else { + // Aggregate initialization. + // std::unique_ptr(new Pair{first, second}); + // Has to be replaced with: + // std::make_unique(Pair{first, second}); + InitRange = SourceRange( + New->getAllocatedTypeSourceInfo()->getTypeLoc().getLocStart(), + New->getInitializer()->getSourceRange().getEnd()); +} Diag << FixItHint::CreateRemoval( -SourceRange(NewStart, InitRange.getBegin().getLocWithOffset(-1))); +CharSourceRange::getCharRange(NewStart, InitRange.getBegin())); Diag << FixItHint::CreateRemoval( SourceRange(InitRange.getEnd().getLocWithOffset(1), NewEnd)); break; Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp?rev=250283&r1=250282&r2=250283&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Wed Oct 14 04:22:32 2015 @@ -34,12 +34,22 @@ struct Derived : public Base { Derived(int, int); }; -struct Pair { +struct APair { int a, b; }; +struct DPair { + DPair() : a(0), b(0) {} + DPair(int x, int y) : a(y), b(x) {} + int a, b; +}; + +struct Empty {}; + template using unique_ptr_ = std::unique_ptr; +void *operator new(unsigned long Count, void *Ptr); + int g(std::unique_ptr P); std::unique_ptr getPointer() { @@ -48,7 +58,7 @@ std::unique_ptr getPointer() { // CHECK-FIXES: return std::make_unique(); } -void f() { +void basic() {
[clang-tools-extra] r250284 - Prevent modernize-use-auto from emitting a warning when 'auto' was already being used.
Author: angelgarcia Date: Wed Oct 14 04:29:55 2015 New Revision: 250284 URL: http://llvm.org/viewvc/llvm-project?rev=250284&view=rev Log: Prevent modernize-use-auto from emitting a warning when 'auto' was already being used. Summary: This fixes https://llvm.org/bugs/show_bug.cgi?id=25082 . Reviewers: bkramer, klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D13504 Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp?rev=250284&r1=250283&r2=250284&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp Wed Oct 14 04:29:55 2015 @@ -222,6 +222,9 @@ StatementMatcher makeDeclWithNewMatcher( has(varDecl()), unless(has(varDecl(anyOf( unless(hasInitializer(ignoringParenImpCasts(cxxNewExpr(, + // Skip declarations that are already using auto. + anyOf(hasType(autoType()), + hasType(pointerType(pointee(autoType(), // FIXME: TypeLoc information is not reliable where CV // qualifiers are concerned so these types can't be // handled for now. Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp?rev=250284&r1=250283&r2=250284&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-new.cpp Wed Oct 14 04:29:55 2015 @@ -95,4 +95,9 @@ void auto_new() { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new // CHECK-FIXES: auto g = new int*, h = new int_p; } + + // Don't warn when 'auto' is already being used. + auto aut = new MyType(); + auto *paut = new MyType(); + const auto *pcaut = new MyType(); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r250288 - Use __SIZE_TYPE__ to fix buildbot failures.
Author: angelgarcia Date: Wed Oct 14 05:30:32 2015 New Revision: 250288 URL: http://llvm.org/viewvc/llvm-project?rev=250288&view=rev Log: Use __SIZE_TYPE__ to fix buildbot failures. Summary: Use __SIZE_TYPE__ to fix buildbot failures. Reviewers: klimek Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D13720 Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp?rev=250288&r1=250287&r2=250288&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Wed Oct 14 05:30:32 2015 @@ -48,7 +48,7 @@ struct Empty {}; template using unique_ptr_ = std::unique_ptr; -void *operator new(unsigned long Count, void *Ptr); +void *operator new(__SIZE_TYPE__ Count, void *Ptr); int g(std::unique_ptr P); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r250509 - Fix overlapping replacements in clang-tidy.
Author: angelgarcia Date: Fri Oct 16 06:43:49 2015 New Revision: 250509 URL: http://llvm.org/viewvc/llvm-project?rev=250509&view=rev Log: Fix overlapping replacements in clang-tidy. Summary: Prevent clang-tidy from applying fixes to errors that overlap with other errors' fixes, with one exception: if one fix is completely contained inside another one, then we can apply the big one. Reviewers: bkramer, klimek Subscribers: djasper, cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D13516 Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h clang-tools-extra/trunk/unittests/clang-tidy/OverlappingReplacementsTest.cpp Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=250509&r1=250508&r2=250509&view=diff == --- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Fri Oct 16 06:43:49 2015 @@ -22,8 +22,8 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Frontend/DiagnosticRenderer.h" #include "llvm/ADT/SmallString.h" -#include #include +#include using namespace clang; using namespace tidy; @@ -146,8 +146,7 @@ static llvm::Regex ConsumeGlob(StringRef } GlobList::GlobList(StringRef Globs) -: Positive(!ConsumeNegativeIndicator(Globs)), - Regex(ConsumeGlob(Globs)), +: Positive(!ConsumeNegativeIndicator(Globs)), Regex(ConsumeGlob(Globs)), NextGlob(Globs.empty() ? nullptr : new GlobList(Globs)) {} bool GlobList::contains(StringRef S, bool Contains) { @@ -222,9 +221,7 @@ const ClangTidyOptions &ClangTidyContext return CurrentOptions; } -void ClangTidyContext::setCheckProfileData(ProfileData *P) { - Profile = P; -} +void ClangTidyContext::setCheckProfileData(ProfileData *P) { Profile = P; } GlobList &ClangTidyContext::getChecksFilter() { assert(CheckFilter != nullptr); @@ -296,16 +293,16 @@ void ClangTidyDiagnosticConsumer::Handle // This is a compiler diagnostic without a warning option. Assign check // name based on its level. switch (DiagLevel) { -case DiagnosticsEngine::Error: -case DiagnosticsEngine::Fatal: - CheckName = "clang-diagnostic-error"; - break; -case DiagnosticsEngine::Warning: - CheckName = "clang-diagnostic-warning"; - break; -default: - CheckName = "clang-diagnostic-unknown"; - break; + case DiagnosticsEngine::Error: + case DiagnosticsEngine::Fatal: +CheckName = "clang-diagnostic-error"; +break; + case DiagnosticsEngine::Warning: +CheckName = "clang-diagnostic-warning"; +break; + default: +CheckName = "clang-diagnostic-unknown"; +break; } } @@ -340,7 +337,7 @@ bool ClangTidyDiagnosticConsumer::passes unsigned LineNumber) const { if (Context.getGlobalOptions().LineFilter.empty()) return true; - for (const FileFilter& Filter : Context.getGlobalOptions().LineFilter) { + for (const FileFilter &Filter : Context.getGlobalOptions().LineFilter) { if (FileName.endswith(Filter.Name)) { if (Filter.LineRanges.empty()) return true; @@ -398,26 +395,147 @@ llvm::Regex *ClangTidyDiagnosticConsumer return HeaderFilter.get(); } +void ClangTidyDiagnosticConsumer::removeIncompatibleErrors( +SmallVectorImpl &Errors) const { + // Each error is modelled as the set of intervals in which it applies + // replacements. To detect overlapping replacements, we use a sweep line + // algorithm over these sets of intervals. + // An event here consists of the opening or closing of an interval. During the + // proccess, we maintain a counter with the amount of open intervals. If we + // find an endpoint of an interval and this counter is different from 0, it + // means that this interval overlaps with another one, so we set it as + // inapplicable. + struct Event { +// An event can be either the begin or the end of an interval. +enum EventType { + ET_Begin = 1, + ET_End = -1, +}; + +Event(unsigned Begin, unsigned End, EventType Type, unsigned ErrorId, + unsigned ErrorSize) +: Type(Type), ErrorId(ErrorId) { + // The events are going to be sorted by their position. In case of draw: + // + // * If an interval ends at the same position at which other interval + // begins, this is not an overlapping, so we want to remove the ending + // interval before adding the starting one: end events have higher + // priority than begin events. + // + // * If we have several begin points
[clang-tools-extra] r250523 - Replacements in different files do not overlap.
Author: angelgarcia Date: Fri Oct 16 11:15:27 2015 New Revision: 250523 URL: http://llvm.org/viewvc/llvm-project?rev=250523&view=rev Log: Replacements in different files do not overlap. Summary: Prevent clang-tidy from discarding fixes that are in different files but happen to have the same file offset. Reviewers: klimek, bkramer Subscribers: bkramer, alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13810 Added: clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/ clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/o.h clang-tools-extra/trunk/test/clang-tidy/overlapping.cpp Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=250523&r1=250522&r2=250523&view=diff == --- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Fri Oct 16 11:15:27 2015 @@ -469,34 +469,40 @@ void ClangTidyDiagnosticConsumer::remove } // Build events from error intervals. - std::vector Events; + std::map> FileEvents; for (unsigned I = 0; I < Errors.size(); ++I) { for (const auto &Replace : Errors[I].Fix) { unsigned Begin = Replace.getOffset(); unsigned End = Begin + Replace.getLength(); + const std::string &FilePath = Replace.getFilePath(); // FIXME: Handle empty intervals, such as those from insertions. if (Begin == End) continue; - Events.push_back(Event(Begin, End, Event::ET_Begin, I, Sizes[I])); - Events.push_back(Event(Begin, End, Event::ET_End, I, Sizes[I])); + FileEvents[FilePath].push_back( + Event(Begin, End, Event::ET_Begin, I, Sizes[I])); + FileEvents[FilePath].push_back( + Event(Begin, End, Event::ET_End, I, Sizes[I])); } } - std::sort(Events.begin(), Events.end()); - // Sweep. std::vector Apply(Errors.size(), true); - int OpenIntervals = 0; - for (const auto &Event : Events) { -if (Event.Type == Event::ET_End) - --OpenIntervals; -// This has to be checked after removing the interval from the count if it -// is an end event, or before adding it if it is a begin event. -if (OpenIntervals != 0) - Apply[Event.ErrorId] = false; -if (Event.Type == Event::ET_Begin) - ++OpenIntervals; + for (auto &FileAndEvents : FileEvents) { +std::vector &Events = FileAndEvents.second; +// Sweep. +std::sort(Events.begin(), Events.end()); +int OpenIntervals = 0; +for (const auto &Event : Events) { + if (Event.Type == Event::ET_End) +--OpenIntervals; + // This has to be checked after removing the interval from the count if it + // is an end event, or before adding it if it is a begin event. + if (OpenIntervals != 0) +Apply[Event.ErrorId] = false; + if (Event.Type == Event::ET_Begin) +++OpenIntervals; +} +assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match"); } - assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match"); for (unsigned I = 0; I < Errors.size(); ++I) { if (!Apply[I]) { Added: clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/o.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/o.h?rev=250523&view=auto == --- clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/o.h (added) +++ clang-tools-extra/trunk/test/clang-tidy/Inputs/overlapping/o.h Fri Oct 16 11:15:27 2015 @@ -0,0 +1,9 @@ +// run: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \ +// run: -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \ +// run: not grep "note: this fix will not be applied because it overlaps with another fix" + +#include "b.h" +#include "a.h" + +// The comments above are there to match the offset of the #include with the +// offset of the #includes in the .cpp file. Added: clang-tools-extra/trunk/test/clang-tidy/overlapping.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/overlapping.cpp?rev=250523&view=auto == --- clang-tools-extra/trunk/test/clang-tidy/overlapping.cpp (added) +++ clang-tools-extra/trunk/test/clang-tidy/overlapping.cpp Fri Oct 16 11:15:27 2015 @@ -0,0 +1,10 @@ +// RUN: clang-tidy -checks=-*,llvm-include-order -header-filter=.* %s \ +// RUN: -- -isystem %S/Inputs/Headers -I %S/Inputs/overlapping | \ +// RUN: not grep "note: this fix will not be applied because it overlaps with another fix" + +#include +#include "o.h" + +// Test that clang-tid
[clang-tools-extra] r250824 - Apply modernize-use-default to clang-tools-extra.
Author: angelgarcia Date: Tue Oct 20 07:56:27 2015 New Revision: 250824 URL: http://llvm.org/viewvc/llvm-project?rev=250824&view=rev Log: Apply modernize-use-default to clang-tools-extra. Summary: Replace empty bodies of default constructors and destructors with '= default'. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13889 Modified: clang-tools-extra/trunk/clang-modernize/Core/IncludeDirectives.cpp clang-tools-extra/trunk/clang-modernize/Core/Transform.cpp clang-tools-extra/trunk/clang-query/Query.cpp clang-tools-extra/trunk/clang-tidy/ClangTidyModule.h clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h clang-tools-extra/trunk/clang-tidy/utils/IncludeInserter.cpp clang-tools-extra/trunk/modularize/CoverageChecker.cpp clang-tools-extra/trunk/modularize/PreprocessorTracker.cpp clang-tools-extra/trunk/pp-trace/PPCallbacksTracker.cpp clang-tools-extra/trunk/unittests/clang-tidy/IncludeInserterTest.cpp Modified: clang-tools-extra/trunk/clang-modernize/Core/IncludeDirectives.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-modernize/Core/IncludeDirectives.cpp?rev=250824&r1=250823&r2=250824&view=diff == --- clang-tools-extra/trunk/clang-modernize/Core/IncludeDirectives.cpp (original) +++ clang-tools-extra/trunk/clang-modernize/Core/IncludeDirectives.cpp Tue Oct 20 07:56:27 2015 @@ -60,7 +60,7 @@ class IncludeDirectivesPPCallback : publ public: IncludeDirectivesPPCallback(IncludeDirectives *Self) : Self(Self), Guard(nullptr) {} - ~IncludeDirectivesPPCallback() override {} + ~IncludeDirectivesPPCallback() override = default; private: void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, Modified: clang-tools-extra/trunk/clang-modernize/Core/Transform.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-modernize/Core/Transform.cpp?rev=250824&r1=250823&r2=250824&view=diff == --- clang-tools-extra/trunk/clang-modernize/Core/Transform.cpp (original) +++ clang-tools-extra/trunk/clang-modernize/Core/Transform.cpp Tue Oct 20 07:56:27 2015 @@ -82,7 +82,7 @@ Transform::Transform(llvm::StringRef Nam Reset(); } -Transform::~Transform() {} +Transform::~Transform() = default; bool Transform::isFileModifiable(const SourceManager &SM, SourceLocation Loc) const { @@ -150,7 +150,7 @@ Version Version::getFromString(llvm::Str return V; } -TransformFactory::~TransformFactory() {} +TransformFactory::~TransformFactory() = default; namespace { bool versionSupported(Version Required, Version AvailableSince) { Modified: clang-tools-extra/trunk/clang-query/Query.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/Query.cpp?rev=250824&r1=250823&r2=250824&view=diff == --- clang-tools-extra/trunk/clang-query/Query.cpp (original) +++ clang-tools-extra/trunk/clang-query/Query.cpp Tue Oct 20 07:56:27 2015 @@ -20,7 +20,7 @@ using namespace clang::ast_matchers::dyn namespace clang { namespace query { -Query::~Query() {} +Query::~Query() = default; bool InvalidQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const { OS << ErrStr << "\n"; Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyModule.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyModule.h?rev=250824&r1=250823&r2=250824&view=diff == --- clang-tools-extra/trunk/clang-tidy/ClangTidyModule.h (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyModule.h Tue Oct 20 07:56:27 2015 @@ -82,7 +82,7 @@ private: /// them a prefixed name. class ClangTidyModule { public: - virtual ~ClangTidyModule() {} + virtual ~ClangTidyModule() = default; /// \brief Implement this function in order to register all \c CheckFactories /// belonging to this module. Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h?rev=250824&r1=250823&r2=250824&view=diff == --- clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h (original) +++ clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h Tue Oct 20 07:56:27 2015 @@ -88,7 +88,7 @@ struct ClangTidyOptions { /// \brief Abstract interface for retrieving various ClangTidy options. class ClangTidyOptionsProvider { public: - virtual ~ClangTidyOptionsProvider() {} + virtual ~ClangTidyOptionsProvider() = default; /// \brief Returns global options, which are independent of the file. virtual const ClangTidyGlobalOptions &getGlobalOptions
[clang-tools-extra] r250897 - Add modernize-use-default check to clang-tidy.
Author: angelgarcia Date: Wed Oct 21 07:58:15 2015 New Revision: 250897 URL: http://llvm.org/viewvc/llvm-project?rev=250897&view=rev Log: Add modernize-use-default check to clang-tidy. Summary: Add a check that replaces empty bodies of special member functions with '= default;'. For now, it is only implemented for the default constructor and the destructor, which are the easier cases. The copy-constructor and the copy-assignment operator cases will be implemented later. I applied this check to the llvm code base and found 627 warnings (385 in llvm, 9 in compiler-rt, 220 in clang and 13 in clang-tools-extra). Applying the fixes didn't break any build or test, it only caused a -Wpedantic warning in lib/Target/Mips/MipsOptionRecord.h:33 becaused it replaced virtual ~MipsOptionRecord(){}; to virtual ~MipsOptionRecord()= default;; Reviewers: klimek Subscribers: george.burgess.iv, Eugene.Zelenko, alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13871 Added: clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.h clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-default.rst clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt?rev=250897&r1=250896&r2=250897&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Wed Oct 21 07:58:15 2015 @@ -9,6 +9,7 @@ add_clang_library(clangTidyModernizeModu ReplaceAutoPtrCheck.cpp ShrinkToFitCheck.cpp UseAutoCheck.cpp + UseDefaultCheck.cpp UseNullptrCheck.cpp UseOverrideCheck.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp?rev=250897&r1=250896&r2=250897&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Wed Oct 21 07:58:15 2015 @@ -16,6 +16,7 @@ #include "ReplaceAutoPtrCheck.h" #include "ShrinkToFitCheck.h" #include "UseAutoCheck.h" +#include "UseDefaultCheck.h" #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" @@ -29,13 +30,13 @@ class ModernizeModule : public ClangTidy public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck("modernize-loop-convert"); -CheckFactories.registerCheck( -"modernize-make-unique"); +CheckFactories.registerCheck("modernize-make-unique"); CheckFactories.registerCheck("modernize-pass-by-value"); CheckFactories.registerCheck( "modernize-replace-auto-ptr"); CheckFactories.registerCheck("modernize-shrink-to-fit"); CheckFactories.registerCheck("modernize-use-auto"); +CheckFactories.registerCheck("modernize-use-default"); CheckFactories.registerCheck("modernize-use-nullptr"); CheckFactories.registerCheck("modernize-use-override"); } @@ -45,7 +46,7 @@ public: auto &Opts = Options.CheckOptions; Opts["modernize-loop-convert.MinConfidence"] = "reasonable"; Opts["modernize-loop-convert.NamingStyle"] = "CamelCase"; -Opts["modernize-pass-by-value.IncludeStyle"] = "llvm"; // Also: "google". +Opts["modernize-pass-by-value.IncludeStyle"] = "llvm";// Also: "google". Opts["modernize-replace-auto-ptr.IncludeStyle"] = "llvm"; // Also: "google". // Comma-separated list of macros that behave like NULL. Added: clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp?rev=250897&view=auto == --- clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp (added) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp Wed Oct 21 07:58:15 2015 @@ -0,0 +1,63 @@ +//===--- UseDefaultCheck.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 "UseDefaultCheck.h" +#include "clang/AST
[clang-tools-extra] r251005 - Make string constants in the modernize module static.
Author: angelgarcia Date: Thu Oct 22 04:48:23 2015 New Revision: 251005 URL: http://llvm.org/viewvc/llvm-project?rev=251005&view=rev Log: Make string constants in the modernize module static. Summary: Add static to global variables, if they are not in an anonymous namespace. Reviewers: klimek Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D13975 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=251005&r1=251004&r2=251005&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Thu Oct 22 04:48:23 2015 @@ -19,19 +19,19 @@ namespace clang { namespace tidy { namespace modernize { -const char LoopNameArray[] = "forLoopArray"; -const char LoopNameIterator[] = "forLoopIterator"; -const char LoopNamePseudoArray[] = "forLoopPseudoArray"; -const char ConditionBoundName[] = "conditionBound"; -const char ConditionVarName[] = "conditionVar"; -const char IncrementVarName[] = "incrementVar"; -const char InitVarName[] = "initVar"; -const char BeginCallName[] = "beginCall"; -const char EndCallName[] = "endCall"; -const char ConditionEndVarName[] = "conditionEndVar"; -const char EndVarName[] = "endVar"; -const char DerefByValueResultName[] = "derefByValueResult"; -const char DerefByRefResultName[] = "derefByRefResult"; +static const char LoopNameArray[] = "forLoopArray"; +static const char LoopNameIterator[] = "forLoopIterator"; +static const char LoopNamePseudoArray[] = "forLoopPseudoArray"; +static const char ConditionBoundName[] = "conditionBound"; +static const char ConditionVarName[] = "conditionVar"; +static const char IncrementVarName[] = "incrementVar"; +static const char InitVarName[] = "initVar"; +static const char BeginCallName[] = "beginCall"; +static const char EndCallName[] = "endCall"; +static const char ConditionEndVarName[] = "conditionEndVar"; +static const char EndVarName[] = "endVar"; +static const char DerefByValueResultName[] = "derefByValueResult"; +static const char DerefByRefResultName[] = "derefByRefResult"; // shared matchers static const TypeMatcher AnyType = anything(); Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp?rev=251005&r1=251004&r2=251005&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp Thu Oct 22 04:48:23 2015 @@ -18,9 +18,9 @@ namespace clang { namespace tidy { namespace modernize { -const char PointerType[] = "pointerType"; -const char ConstructorCall[] = "constructorCall"; -const char NewExpression[] = "newExpression"; +static const char PointerType[] = "pointerType"; +static const char ConstructorCall[] = "constructorCall"; +static const char NewExpression[] = "newExpression"; void MakeUniqueCheck::registerMatchers(MatchFinder *Finder) { if (getLangOpts().CPlusPlus11) { Modified: clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp?rev=251005&r1=251004&r2=251005&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp Thu Oct 22 04:48:23 2015 @@ -21,8 +21,8 @@ namespace clang { namespace tidy { namespace modernize { -const char AutoPtrTokenId[] = "AutoPrTokenId"; -const char AutoPtrOwnershipTransferId[] = "AutoPtrOwnershipTransferId"; +static const char AutoPtrTokenId[] = "AutoPrTokenId"; +static const char AutoPtrOwnershipTransferId[] = "AutoPtrOwnershipTransferId"; /// \brief Matches expressions that are lvalues. /// ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r251013 - Correctly print the type in modernize-make-unique.
Author: angelgarcia Date: Thu Oct 22 08:20:49 2015 New Revision: 251013 URL: http://llvm.org/viewvc/llvm-project?rev=251013&view=rev Log: Correctly print the type in modernize-make-unique. Summary: Take into account the current LangOptions the check has to add back the template argument. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13983 Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp?rev=251013&r1=251012&r2=251013&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp Thu Oct 22 08:20:49 2015 @@ -79,8 +79,8 @@ void MakeUniqueCheck::check(const MatchF // If the template argument is missing (because it is part of the alias) // we have to add it back. ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size()); -Diag << FixItHint::CreateInsertion(ConstructCallEnd, - "<" + Type->getAsString() + ">"); +Diag << FixItHint::CreateInsertion( +ConstructCallEnd, "<" + Type->getAsString(getLangOpts()) + ">"); } else { ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle); } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp?rev=251013&r1=251012&r2=251013&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Thu Oct 22 08:20:49 2015 @@ -163,6 +163,18 @@ void aliases() { // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_unique instead // CHECK-FIXES: IntPtr Typedef = std::make_unique(); + // We use 'bool' instead of '_Bool'. + typedef std::unique_ptr BoolPtr; + BoolPtr BoolType = BoolPtr(new bool); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_unique instead + // CHECK-FIXES: BoolPtr BoolType = std::make_unique(); + + // We use 'Base' instead of 'struct Base'. + typedef std::unique_ptr BasePtr; + BasePtr StructType = BasePtr(new Base); + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead + // CHECK-FIXES: BasePtr StructType = std::make_unique(); + #define PTR unique_ptr std::unique_ptr Macro = std::PTR(new int); // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r251015 - Don't use "auto" on loops over fundamental types in modernize-loop-convert.
Author: angelgarcia Date: Thu Oct 22 08:23:46 2015 New Revision: 251015 URL: http://llvm.org/viewvc/llvm-project?rev=251015&view=rev Log: Don't use "auto" on loops over fundamental types in modernize-loop-convert. Summary: using "auto" on a loop that iterates over ints is kind of an overkill. Use the real type name instead. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D13982 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-camelback.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-lowercase.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-uppercase.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=251015&r1=251014&r2=251015&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Thu Oct 22 08:23:46 2015 @@ -405,7 +405,7 @@ static bool containerIsConst(const Expr LoopConvertCheck::RangeDescriptor::RangeDescriptor() : ContainerNeedsDereference(false), DerefByConstRef(false), - DerefByValue(false), IsTriviallyCopyable(false) {} + DerefByValue(false) {} LoopConvertCheck::LoopConvertCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), TUInfo(new TUTrackingInfo), @@ -554,30 +554,33 @@ void LoopConvertCheck::doConversion( // Now, we need to construct the new range expression. SourceRange ParenRange(Loop->getLParenLoc(), Loop->getRParenLoc()); - QualType AutoType = Context->getAutoDeductType(); + QualType Type = Context->getAutoDeductType(); + if (!Descriptor.ElemType.isNull() && Descriptor.ElemType->isFundamentalType()) +Type = Descriptor.ElemType.getUnqualifiedType(); // If the new variable name is from the aliased variable, then the reference // type for the new variable should only be used if the aliased variable was // declared as a reference. + bool IsTriviallyCopyable = + !Descriptor.ElemType.isNull() && + Descriptor.ElemType.isTriviallyCopyableType(*Context); bool UseCopy = - CanCopy && - ((VarNameFromAlias && !AliasVarIsRef) || - (Descriptor.DerefByConstRef && Descriptor.IsTriviallyCopyable)); + CanCopy && ((VarNameFromAlias && !AliasVarIsRef) || + (Descriptor.DerefByConstRef && IsTriviallyCopyable)); if (!UseCopy) { if (Descriptor.DerefByConstRef) { - AutoType = - Context->getLValueReferenceType(Context->getConstType(AutoType)); + Type = Context->getLValueReferenceType(Context->getConstType(Type)); } else if (Descriptor.DerefByValue) { - if (!Descriptor.IsTriviallyCopyable) -AutoType = Context->getRValueReferenceType(AutoType); + if (!IsTriviallyCopyable) +Type = Context->getRValueReferenceType(Type); } else { - AutoType = Context->getLValueReferenceType(AutoType); + Type = Context->getLValueReferenceType(Type); } } StringRef MaybeDereference = Descriptor.ContainerNeedsDereference ? "*" : ""; - std::string TypeString = AutoType.getAsString(); + std::string TypeString = Type.getAsString(getLangOpts()); std::string Range = ("(" + TypeString + " " + VarName + " : " + MaybeDereference + Descriptor.ContainerString + ")") .str(); @@ -633,7 +636,7 @@ void LoopConvertCheck::getArrayLoopQuali } Type = Type->getPointeeType(); } -Descriptor.IsTriviallyCopyable = Type.isTriviallyCopyableType(*Context); +Descriptor.ElemType = Type; } } @@ -654,8 +657,7 @@ void LoopConvertCheck::getIteratorLoopQu // If the dereference operator returns by value then test for the // canonical const qualification of the init variable type. Descriptor.DerefByConstRef = CanonicalInitVarType.isConstQualified(); -Descriptor.IsTriviallyCopyable = -DerefByValueType->isTriviallyCopyableType(*Context); +Descriptor.ElemType = *DerefByValueType; } else { if (const auto *DerefType = Nodes.getNodeAs(DerefByRefResultName)) { @@ -665,8 +667,7 @@ void LoopConvertCheck::getIteratorLoopQu auto ValueType = DerefType->getNonReferenceType(); Descriptor.DerefByConstRef = ValueType.isConstQualified(); - Descriptor.IsTriviallyCopyable = - ValueType.isTriviallyCopyableType(*Context); + Descriptor.ElemType = ValueType; } else {
r251693 - Add "equalsNode" for types and "isCopyAssignmentOperator" matchers.
Author: angelgarcia Date: Fri Oct 30 04:35:51 2015 New Revision: 251693 URL: http://llvm.org/viewvc/llvm-project?rev=251693&view=rev Log: Add "equalsNode" for types and "isCopyAssignmentOperator" matchers. Summary: This matchers are going to be used in modernize-use-default, but are generic enough to be placed in ASTMatchers.h. Reviewers: klimek Subscribers: alexfh, cfe-commits, klimek Differential Revision: http://reviews.llvm.org/D14152 Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=251693&r1=251692&r2=251693&view=diff == --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Fri Oct 30 04:35:51 2015 @@ -3385,6 +3385,23 @@ AST_MATCHER(CXXMethodDecl, isConst) { return Node.isConst(); } +/// \brief Matches if the given method declaration declares a copy assignment +/// operator. +/// +/// Given +/// \code +/// struct A { +/// A &operator=(const A &); +/// A &operator=(A &&); +/// }; +/// \endcode +/// +/// cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not +/// the second one. +AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) { + return Node.isCopyAssignmentOperator(); +} + /// \brief Matches if the given method declaration overrides another method. /// /// Given @@ -4307,10 +4324,15 @@ AST_MATCHER_P_OVERLOAD(Decl, equalsNode, /// \brief Matches if a node equals another node. /// /// \c Stmt has pointer identity in the AST. -/// AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) { return &Node == Other; } +/// \brief Matches if a node equals another node. +/// +/// \c Type has pointer identity in the AST. +AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) { +return &Node == Other; +} /// @} Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=251693&r1=251692&r2=251693&view=diff == --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Fri Oct 30 04:35:51 2015 @@ -1890,6 +1890,21 @@ TEST(Matcher, MatchesPureMethod) { EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure(; } +TEST(Matcher, MatchesCopyAssignmentOperator) { + EXPECT_TRUE(matches("class X { X &operator=(X); };", + cxxMethodDecl(isCopyAssignmentOperator(; + EXPECT_TRUE(matches("class X { X &operator=(X &); };", + cxxMethodDecl(isCopyAssignmentOperator(; + EXPECT_TRUE(matches("class X { X &operator=(const X &); };", + cxxMethodDecl(isCopyAssignmentOperator(; + EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };", + cxxMethodDecl(isCopyAssignmentOperator(; + EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };", + cxxMethodDecl(isCopyAssignmentOperator(; + EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };", + cxxMethodDecl(isCopyAssignmentOperator(; +} + TEST(Matcher, MatchesConstMethod) { EXPECT_TRUE( matches("struct A { void foo() const; };", cxxMethodDecl(isConst(; @@ -4671,6 +4686,16 @@ public: decl(has(decl(equalsNode(TypedNode.bind(""))), *Node, Context)) != nullptr; } + bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) { +// Use the original typed pointer to verify we can pass pointers to subtypes +// to equalsNode. +const T *TypedNode = cast(Node); +const auto *Dec = Nodes.getNodeAs("decl"); +return selectFirst( + "", match(fieldDecl(hasParent(decl(has(fieldDecl( + hasType(type(equalsNode(TypedNode)).bind(""))), + *Dec, Context)) != nullptr; + } }; TEST(IsEqualTo, MatchesNodesByIdentity) { @@ -4680,6 +4705,10 @@ TEST(IsEqualTo, MatchesNodesByIdentity) EXPECT_TRUE(matchAndVerifyResultTrue( "void f() { if (true) if(true) {} }", ifStmt().bind(""), new VerifyAncestorHasChildIsEqual())); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class X { class Y {} y; };", + fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"), + new VerifyAncestorHasChildIsEqual())); } TEST(MatchFinder, CheckProfiling) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r251694 - Only copy small types in modernize-loop-convert.
Author: angelgarcia Date: Fri Oct 30 04:37:57 2015 New Revision: 251694 URL: http://llvm.org/viewvc/llvm-project?rev=251694&view=rev Log: Only copy small types in modernize-loop-convert. Summary: If the size of the type is above a certain bound, we'll take a const reference. This bound can be set as an option. For now, the default value is 16 bytes. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D14176 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-loop-convert/structures.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=251694&r1=251693&r2=251694&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Fri Oct 30 04:37:57 2015 @@ -230,18 +230,18 @@ StatementMatcher makePseudoArrayLoopMatc // FIXME: Also, a record doesn't necessarily need begin() and end(). Free // functions called begin() and end() taking the container as an argument // are also allowed. - TypeMatcher RecordWithBeginEnd = qualType( - anyOf(qualType(isConstQualified(), - hasDeclaration(cxxRecordDecl( - hasMethod(cxxMethodDecl(hasName("begin"), isConst())), - hasMethod(cxxMethodDecl(hasName("end"), - isConst() // hasDeclaration - ),// qualType -qualType(unless(isConstQualified()), - hasDeclaration( - cxxRecordDecl(hasMethod(hasName("begin")), + TypeMatcher RecordWithBeginEnd = qualType(anyOf( + qualType(isConstQualified(), + hasDeclaration(cxxRecordDecl( + hasMethod(cxxMethodDecl(hasName("begin"), isConst())), + hasMethod(cxxMethodDecl(hasName("end"), + isConst() // hasDeclaration + ),// qualType + qualType( + unless(isConstQualified()), + hasDeclaration(cxxRecordDecl(hasMethod(hasName("begin")), hasMethod(hasName("end") // qualType -)); + )); StatementMatcher SizeCallMatcher = cxxMemberCallExpr( argumentCountIs(0), @@ -409,6 +409,7 @@ LoopConvertCheck::RangeDescriptor::Range LoopConvertCheck::LoopConvertCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), TUInfo(new TUTrackingInfo), + MaxCopySize(std::stoull(Options.get("MaxCopySize", "16"))), MinConfidence(StringSwitch( Options.get("MinConfidence", "reasonable")) .Case("safe", Confidence::CL_Safe) @@ -422,6 +423,7 @@ LoopConvertCheck::LoopConvertCheck(Strin .Default(VariableNamer::NS_CamelCase)) {} void LoopConvertCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "MaxCopySize", std::to_string(MaxCopySize)); SmallVector Confs{"risky", "reasonable", "safe"}; Options.store(Opts, "MinConfidence", Confs[static_cast(MinConfidence)]); @@ -561,18 +563,20 @@ void LoopConvertCheck::doConversion( // If the new variable name is from the aliased variable, then the reference // type for the new variable should only be used if the aliased variable was // declared as a reference. - bool IsTriviallyCopyable = + bool IsCheapToCopy = !Descriptor.ElemType.isNull() && - Descriptor.ElemType.isTriviallyCopyableType(*Context); + Descriptor.ElemType.isTriviallyCopyableType(*Context) && + // TypeInfo::Width is in bits. + Context->getTypeInfo(Descriptor.ElemType).Width <= 8 * MaxCopySize; bool UseCopy = CanCopy && ((VarNameFromAlias && !AliasVarIsRef) || - (Descriptor.DerefByConstRef && IsTriviallyCopyable)); + (Descriptor.DerefByConstRef && IsCheapToCopy)); if (!UseCopy) { if (Descriptor.DerefByConstRef) { Type = Context->getLValueReferenceType(Context->getConstType(Type)); } else if (Descriptor.DerefByValue) { - if (!IsTriviallyCopyable) + if (!IsCheapToCopy) Type = Context->getRValueReferenceType(Type); } else { Type = Context->getLValueReferenceType(Type); Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h URL: http:
[clang-tools-extra] r251788 - modernize-use-default supports copy constructor and copy-assignment operator.
Author: angelgarcia Date: Mon Nov 2 04:34:19 2015 New Revision: 251788 URL: http://llvm.org/viewvc/llvm-project?rev=251788&view=rev Log: modernize-use-default supports copy constructor and copy-assignment operator. Summary: the check will now warn when the user provided definitions of this functions is equivalent to the explicitly defaulted ones. Reviewers: klimek Subscribers: klimek, cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D14145 Added: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp?rev=251788&r1=251787&r2=251788&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseDefaultCheck.cpp Mon Nov 2 04:34:19 2015 @@ -10,6 +10,7 @@ #include "UseDefaultCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; @@ -17,45 +18,302 @@ namespace clang { namespace tidy { namespace modernize { -static const char CtorDtor[] = "CtorDtorDecl"; +static const char SpecialFunction[] = "SpecialFunction"; + +/// \brief Finds the SourceLocation of the colon ':' before the initialization +/// list in the definition of a constructor. +static SourceLocation getColonLoc(const ASTContext *Context, + const CXXConstructorDecl *Ctor) { + // FIXME: First init is the first initialization that is going to be + // performed, no matter what was the real order in the source code. If the + // order of the inits is wrong in the code, it may result in a false negative. + SourceLocation FirstInit = (*Ctor->init_begin())->getSourceLocation(); + SourceLocation LastArg = + Ctor->getParamDecl(Ctor->getNumParams() - 1)->getLocEnd(); + // We need to find the colon between the ')' and the first initializer. + bool Invalid = false; + StringRef Text = Lexer::getSourceText( + CharSourceRange::getCharRange(LastArg, FirstInit), + Context->getSourceManager(), Context->getLangOpts(), &Invalid); + if (Invalid) +return SourceLocation(); + + size_t ColonPos = Text.rfind(':'); + if (ColonPos == StringRef::npos) +return SourceLocation(); + + Text = Text.drop_front(ColonPos + 1); + if (std::strspn(Text.data(), " \t\r\n") != Text.size()) { +// If there are comments, preprocessor directives or anything, abort. +return SourceLocation(); + } + // FIXME: don't remove comments in the middle of the initializers. + return LastArg.getLocWithOffset(ColonPos); +} + +/// \brief Finds all the named non-static fields of \p Record. +static std::set +getAllNamedFields(const CXXRecordDecl *Record) { + std::set Result; + for (const auto *Field : Record->fields()) { +// Static data members are not in this range. +if (Field->isUnnamedBitfield()) + continue; +Result.insert(Field); + } + return Result; +} + +/// \brief Returns the names of the direct bases of \p Record, both virtual and +/// non-virtual. +static std::set getAllDirectBases(const CXXRecordDecl *Record) { + std::set Result; + for (auto Base : Record->bases()) { +// CXXBaseSpecifier. +const auto *BaseType = Base.getTypeSourceInfo()->getType().getTypePtr(); +Result.insert(BaseType); + } + return Result; +} + +/// \brief Returns a matcher that matches member expressions where the base is +/// the variable declared as \p Var and the accessed member is the one declared +/// as \p Field. +internal::Matcher accessToFieldInVar(const FieldDecl *Field, + const ValueDecl *Var) { + return ignoringImpCasts( + memberExpr(hasObjectExpression(declRefExpr(to(varDecl(equalsNode(Var), + member(fieldDecl(equalsNode(Field); +} + +/// \brief Check that the given constructor has copy signature and that it +/// copy-initializes all its bases and members. +static bool isCopyConstructorAndCanBeDefaulted(ASTContext *Context, + const CXXConstructorDecl *Ctor) { + // An explicitly-defaulted constructor cannot have default arguments. + if (Ctor->getMinRequiredArguments() != 1) +return false; + + const auto *Record = Ctor->getParent(); + const auto *Param = Ctor->getParamDecl(0); + + // Base classes and members that have to be copied. + auto BasesToInit = getAllDirectBases(Record); + auto FieldsToInit = getAllNamedFields(Record); + + // Ensure that all the bases are copied. + for (const auto *Base : BasesToInit) { +// The initialization of a bas
[clang-tools-extra] r251790 - Try to fix buildbots failure.
Author: angelgarcia Date: Mon Nov 2 04:54:50 2015 New Revision: 251790 URL: http://llvm.org/viewvc/llvm-project?rev=251790&view=rev Log: Try to fix buildbots failure. Summary: Add -fexceptions flag to enable exceptions. Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D14225 Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp?rev=251790&r1=251789&r2=251790&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-default-copy.cpp Mon Nov 2 04:54:50 2015 @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing +// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing -fexceptions // Out of line definition. struct OL { Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp?rev=251790&r1=251789&r2=251790&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-default.cpp Mon Nov 2 04:54:50 2015 @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing +// RUN: %check_clang_tidy %s modernize-use-default %t -- -- -std=c++11 -fno-delayed-template-parsing -fexceptions // Out of line definition. class OL { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r251792 - Fix crash in redundant-void-arg check.
Author: angelgarcia Date: Mon Nov 2 05:39:17 2015 New Revision: 251792 URL: http://llvm.org/viewvc/llvm-project?rev=251792&view=rev Log: Fix crash in redundant-void-arg check. Summary: When applying this check to the unit tests, it would hit an assertion: llvm/tools/clang/lib/Lex/Lexer.cpp:1056: clang::SourceLocation clang::Lexer::getSourceLocation(const char*, unsigned int) const: Assertion `PP && "This doesn't work on raw lexers"' failed. Reviewers: klimek, LegalizeAdulthood, alexfh Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D14204 Modified: clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp?rev=251792&r1=251791&r2=251792&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp Mon Nov 2 05:39:17 2015 @@ -47,8 +47,8 @@ namespace modernize { void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(functionDecl(isExpansionInMainFile(), parameterCountIs(0), - unless(isImplicit()), - unless(isExternC())).bind(FunctionId), + unless(isImplicit()), unless(isExternC())) + .bind(FunctionId), this); Finder->addMatcher(typedefDecl(isExpansionInMainFile()).bind(TypedefId), this); @@ -77,9 +77,10 @@ void RedundantVoidArgCheck::registerMatc cxxReinterpretCastExpr(isExpansionInMainFile(), CastDestinationIsFunction) .bind(NamedCastId), this); - Finder->addMatcher(cxxConstCastExpr(isExpansionInMainFile(), - CastDestinationIsFunction).bind(NamedCastId), - this); + Finder->addMatcher( + cxxConstCastExpr(isExpansionInMainFile(), CastDestinationIsFunction) + .bind(NamedCastId), + this); Finder->addMatcher(lambdaExpr(isExpansionInMainFile()).bind(LambdaId), this); } @@ -128,11 +129,14 @@ void RedundantVoidArgCheck::processFunct void RedundantVoidArgCheck::removeVoidArgumentTokens( const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range, StringRef GrammarLocation) { - std::string DeclText = - Lexer::getSourceText(CharSourceRange::getTokenRange(Range), - *Result.SourceManager, - Result.Context->getLangOpts()).str(); - Lexer PrototypeLexer(Range.getBegin(), Result.Context->getLangOpts(), + CharSourceRange CharRange = Lexer::makeFileCharRange( + CharSourceRange::getTokenRange(Range), *Result.SourceManager, + Result.Context->getLangOpts()); + + std::string DeclText = Lexer::getSourceText(CharRange, *Result.SourceManager, + Result.Context->getLangOpts()) + .str(); + Lexer PrototypeLexer(CharRange.getBegin(), Result.Context->getLangOpts(), DeclText.data(), DeclText.data(), DeclText.data() + DeclText.size()); enum TokenState { Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp?rev=251792&r1=251791&r2=251792&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp Mon Nov 2 05:39:17 2015 @@ -417,3 +417,19 @@ void test_lambda_functions() { // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression // CHECK-FIXES: {{^ }}auto void_returner = []() -> void (*)() { return f1; };{{$}} } + +#define M(x) x + +M(void inmacro(void) {}) +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition +// CHECK-FIXES: M(void inmacro() {}) + +#define F(A, B)\ + struct F_##A##_##B { \ +F_##A##_##B(void); \ + }; \ + F_##A##_##B::F_##A##_##B(void) + +F(Foo, Bar) { + +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r251803 - Remove unreachable that was reached in modernize-use-nullptr.
Author: angelgarcia Date: Mon Nov 2 09:28:06 2015 New Revision: 251803 URL: http://llvm.org/viewvc/llvm-project?rev=251803&view=rev Log: Remove unreachable that was reached in modernize-use-nullptr. Summary: When traversing the parent map, the check assumed that all the nodes would be either Stmt or Decl. After r251101, this is no longer true: there can be TypeLoc and NestedNameSpecifierLoc nodes. Reviewers: alexfh Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D14229 Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp?rev=251803&r1=251802&r2=251803&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/UseNullptrCheck.cpp Mon Nov 2 09:28:06 2015 @@ -435,12 +435,14 @@ private: Loc = D->getLocStart(); else if (const auto *S = Parent.get()) Loc = S->getLocStart(); - else -llvm_unreachable("Expected to find Decl or Stmt containing ancestor"); - if (!expandsFrom(Loc, MacroLoc)) { -Result = Parent; -return true; + // TypeLoc and NestedNameSpecifierLoc are members of the parent map. Skip + // them and keep going up. + if (Loc.isValid()) { +if (!expandsFrom(Loc, MacroLoc)) { + Result = Parent; + return true; +} } Start = Parent; } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp?rev=251803&r1=251802&r2=251803&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-nullptr.cpp Mon Nov 2 09:28:06 2015 @@ -184,3 +184,14 @@ void test_macro_args() { // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}}; #undef ENTRY } + +// One of the ancestor of the cast is a NestedNameSpecifierLoc. +class NoDef; +char function(NoDef *p); +#define F(x) (sizeof(function(x)) == 1) +template +class C {}; +C c; +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use nullptr +// CHECK-FIXES: C c; +#undef F ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r251807 - Fix another crash in the redundant-void-arg check.
Author: angelgarcia Date: Mon Nov 2 10:18:23 2015 New Revision: 251807 URL: http://llvm.org/viewvc/llvm-project?rev=251807&view=rev Log: Fix another crash in the redundant-void-arg check. Summary: The check was assuming that a definition of a function always has a body, but a declaration that explicitly defaults or deletes a function is a definition too. Reviewers: alexfh Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D14238 Modified: clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp?rev=251807&r1=251806&r2=251807&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/RedundantVoidArgCheck.cpp Mon Nov 2 10:18:23 2015 @@ -116,9 +116,12 @@ void RedundantVoidArgCheck::processFunct const MatchFinder::MatchResult &Result, const FunctionDecl *Function) { SourceLocation Start = Function->getLocStart(); if (Function->isThisDeclarationADefinition()) { -SourceLocation BeforeBody = -Function->getBody()->getLocStart().getLocWithOffset(-1); -removeVoidArgumentTokens(Result, SourceRange(Start, BeforeBody), +SourceLocation End; +if (Function->hasBody()) + End = Function->getBody()->getLocStart().getLocWithOffset(-1); +else + End = Function->getLocEnd(); +removeVoidArgumentTokens(Result, SourceRange(Start, End), "function definition"); } else { removeVoidArgumentTokens(Result, Function->getSourceRange(), Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp?rev=251807&r1=251806&r2=251807&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-redundant-void-arg.cpp Mon Nov 2 10:18:23 2015 @@ -433,3 +433,9 @@ M(void inmacro(void) {}) F(Foo, Bar) { } + +struct DefinitionWithNoBody { + DefinitionWithNoBody(void) = delete; + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in function definition + // CHECK-FIXES: DefinitionWithNoBody() = delete; +}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r251808 - Make the modernize-loop-convert's const-detection smarter.
Author: angelgarcia Date: Mon Nov 2 11:02:52 2015 New Revision: 251808 URL: http://llvm.org/viewvc/llvm-project?rev=251808&view=rev Log: Make the modernize-loop-convert's const-detection smarter. Summary: Now, it detects that several kinds of usages are can't modify the elements. Examples: -When an usage is a call to a const member function or operator of the element. -If the element is used as an argument to a function or constructor that takes a const-reference or a value. -LValue to RValue conversion, if the element is a fundamental type (which allows the use of most of the builtin operators). Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D14198 Added: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-camelback.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-lowercase.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-uppercase.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=251808&r1=251807&r2=251808&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Mon Nov 2 11:02:52 2015 @@ -368,11 +368,38 @@ static bool isDirectMemberExpr(const Exp return false; } +/// \brief Given an expression that represents an usage of an element from the +/// containter that we are iterating over, returns false when it can be +/// guaranteed this element cannot be modified as a result of this usage. +static bool canBeModified(ASTContext *Context, const Expr *E) { + auto Parents = Context->getParents(*E); + if (Parents.size() != 1) +return true; + if (const auto *Cast = Parents[0].get()) { +if ((Cast->getCastKind() == CK_NoOp && + Cast->getType() == E->getType().withConst()) || +(Cast->getCastKind() == CK_LValueToRValue && + !Cast->getType().isNull() && Cast->getType()->isFundamentalType())) + return false; + } + // FIXME: Make this function more generic. + return true; +} + /// \brief Returns true when it can be guaranteed that the elements of the /// container are not being modified. -static bool usagesAreConst(const UsageResult &Usages) { - // FIXME: Make this function more generic. - return Usages.empty(); +static bool usagesAreConst(ASTContext *Context, const UsageResult &Usages) { + for (const Usage &U : Usages) { +// Lambda captures are just redeclarations (VarDecl) of the same variable, +// not expressions. If we want to know if a variable that is captured by +// reference can be modified in an usage inside the lambda's body, we need +// to find the expression corresponding to that particular usage, later in +// this loop. +if (U.Kind != Usage::UK_CaptureByCopy && U.Kind != Usage::UK_CaptureByRef && +canBeModified(Context, U.Expression)) + return false; + } + return true; } /// \brief Returns true if the elements of the container are never accessed @@ -568,9 +595,8 @@ void LoopConvertCheck::doConversion( Descriptor.ElemType.isTriviallyCopyableType(*Context) && // TypeInfo::Width is in bits. Context->getTypeInfo(Descriptor.ElemType).Width <= 8 * MaxCopySize; - bool UseCopy = - CanCopy && ((VarNameFromAlias && !AliasVarIsRef) || - (Descriptor.DerefByConstRef && IsCheapToCopy)); + bool UseCopy = CanCopy && ((VarNameFromAlias && !AliasVarIsRef) || + (Descriptor.DerefByConstRef && IsCheapToCopy)); if (!UseCopy) { if (Descriptor.DerefByConstRef) { @@ -618,7 +644,7 @@ void LoopConvertCheck::getArrayLoopQuali RangeDescriptor &Descriptor) { // On arrays and pseudoarrays, we must figure out the qualifiers from the // usages. - if (usagesAreConst(Usages) || + if (usagesAreConst(Context, Usages) || containerIsConst(ContainerExpr, Descriptor.ContainerNeedsDereference)) { Descriptor.DerefByConstRef = true; } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp?rev=251808&r1=251807&r2=251808&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp (original) +++ clang-tools-extra/tr
[clang-tools-extra] r251940 - Improve more the const-detection in modernize-loop-convert.
Author: angelgarcia Date: Tue Nov 3 10:31:36 2015 New Revision: 251940 URL: http://llvm.org/viewvc/llvm-project?rev=251940&view=rev Log: Improve more the const-detection in modernize-loop-convert. Summary: The previous change was focused in detecting when a non-const object was used in a constant way. Looks like I forgot the most important and trivial case: when the object is already constant. Failing to detect this cases results in compile errors, due to trying to bind a constant object to a non-const reference in the range-for statement. This change should fix that. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D14282 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=251940&r1=251939&r2=251940&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Tue Nov 3 10:31:36 2015 @@ -372,6 +372,8 @@ static bool isDirectMemberExpr(const Exp /// containter that we are iterating over, returns false when it can be /// guaranteed this element cannot be modified as a result of this usage. static bool canBeModified(ASTContext *Context, const Expr *E) { + if (E->getType().isConstQualified()) +return false; auto Parents = Context->getParents(*E); if (Parents.size() != 1) return true; Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp?rev=251940&r1=251939&r2=251940&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp Tue Nov 3 10:31:36 2015 @@ -271,28 +271,91 @@ void takingReferences() { // Aliases. for (int I = 0; I < N; ++I) { const Str &J = Array[I]; -(void) J; +(void)J; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop // CHECK-FIXES: for (auto J : Array) for (int I = 0; I < N; ++I) { Str &J = Array[I]; -(void) J; +(void)J; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop // CHECK-FIXES: for (auto & J : Array) for (int I = 0; I < N; ++I) { const int &J = Ints[I]; -(void) J; +(void)J; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop // CHECK-FIXES: for (int J : Ints) for (int I = 0; I < N; ++I) { int &J = Ints[I]; -(void) J; +(void)J; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop // CHECK-FIXES: for (int & J : Ints) } + +template +struct vector { + unsigned size() const; + const T &operator[](int) const; + T &operator[](int); + T *begin(); + T *end(); + const T *begin() const; + const T *end() const; +}; + +// If the elements are already constant, we won't do any ImplicitCast to const. +void testContainerOfConstElements() { + const int Ints[N]{}; + for (int I = 0; I < N; ++I) { +OtherInt -= Ints[I]; + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop + // CHECK-FIXES: for (int Int : Ints) + + vector Strs; + for (int I = 0; I < Strs.size(); ++I) { +Strs[I].constMember(0); +constRefArg(Strs[I]); + } + // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop + // CHECK-FIXES: for (auto Str : Strs) +} + +// When we are inside a const-qualified member functions, all the data members +// are implicitly set as const. As before, there won't be any ImplicitCast to +// const in their usages. +class TestInsideConstFunction { + const static int N = 10; + int Ints[N]; + Str Array[N]; + vector V; + + void foo() const { +for (int I = 0; I < N; ++I) { + if (Ints[I]) +copyArg(Ints[I]); +} +// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop +// CHECK-FIXES: for (int Elem : Ints) + +for (int I = 0; I < N; ++I) { + Array[I].constMember(0); + constRefArg(Array[I]); +} +// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop +// CHECK-FIXES: for (auto Elem : Array) + +for (int I = 0; I < V.size(); ++I) { + if (V[I]) +copyArg(V[I]); +} +// CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop +// CHECK-FIXES: for (int Elem : V) + + } +}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llv
[clang-tools-extra] r251943 - Handle correctly containers that are data members in modernize-loop-convert.
Author: angelgarcia Date: Tue Nov 3 10:38:31 2015 New Revision: 251943 URL: http://llvm.org/viewvc/llvm-project?rev=251943&view=rev Log: Handle correctly containers that are data members in modernize-loop-convert. Summary: I recently found that the variable naming wasn't working as expected with containers that are data members. The new index always received the name "Elem" (or equivalent) regardless of the container's name. The check was assuming that the container's declaration was a VarDecl, which cannot be converted to a FieldDecl (a data member), and then it could never retrieve its name. This also fixes some cases where the check failed to find the container at all (so it didn't do any fix) because of the same reason. Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D14289 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-negative.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=251943&r1=251942&r2=251943&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Tue Nov 3 10:38:31 2015 @@ -353,10 +353,12 @@ static StringRef getStringFromRange(Sour } /// \brief If the given expression is actually a DeclRefExpr, find and return -/// the underlying VarDecl; otherwise, return NULL. -static const VarDecl *getReferencedVariable(const Expr *E) { +/// the underlying ValueDecl; otherwise, return NULL. +static const ValueDecl *getReferencedVariable(const Expr *E) { if (const DeclRefExpr *DRE = getDeclRef(E)) return dyn_cast(DRE->getDecl()); + if (const auto *Mem = dyn_cast(E)) +return dyn_cast(Mem->getMemberDecl()); return nullptr; } @@ -500,9 +502,10 @@ void LoopConvertCheck::getAliasRange(Sou /// \brief Computes the changes needed to convert a given for loop, and /// applies them. void LoopConvertCheck::doConversion( -ASTContext *Context, const VarDecl *IndexVar, const VarDecl *MaybeContainer, -const UsageResult &Usages, const DeclStmt *AliasDecl, bool AliasUseRequired, -bool AliasFromForInit, const ForStmt *Loop, RangeDescriptor Descriptor) { +ASTContext *Context, const VarDecl *IndexVar, +const ValueDecl *MaybeContainer, const UsageResult &Usages, +const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit, +const ForStmt *Loop, RangeDescriptor Descriptor) { auto Diag = diag(Loop->getForLoc(), "use range-based for loop instead"); std::string VarName; Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h?rev=251943&r1=251942&r2=251943&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.h Tue Nov 3 10:38:31 2015 @@ -37,7 +37,7 @@ private: void getAliasRange(SourceManager &SM, SourceRange &DeclRange); void doConversion(ASTContext *Context, const VarDecl *IndexVar, -const VarDecl *MaybeContainer, const UsageResult &Usages, +const ValueDecl *MaybeContainer, const UsageResult &Usages, const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit, const ForStmt *Loop, RangeDescriptor Descriptor); Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h?rev=251943&r1=251942&r2=251943&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.h Tue Nov 3 10:38:31 2015 @@ -425,7 +425,7 @@ public: VariableNamer(StmtGeneratedVarNameMap *GeneratedDecls, const StmtParentMap *ReverseAST, const clang::Stmt *SourceStmt, const clang::VarDecl *OldIndex, -const clang::VarDecl *TheContainer, +const clang::ValueDecl *TheContaine
[clang-tools-extra] r252041 - Improve modernize-make-unique matcher.
Author: angelgarcia Date: Wed Nov 4 04:27:51 2015 New Revision: 252041 URL: http://llvm.org/viewvc/llvm-project?rev=252041&view=rev Log: Improve modernize-make-unique matcher. Summary: "std::unique_ptr" is not the same type as "std::unique_ptr>", unless we insert a "hasCanonicalType" in the middle. Probably it also happens in other cases related to default template argument. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D14291 Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp?rev=252041&r1=252040&r2=252041&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp Wed Nov 4 04:27:51 2015 @@ -42,9 +42,10 @@ void MakeUniqueCheck::registerMatchers(M qualType(equalsBoundNode( PointerType))), argumentCountIs(1), -hasArgument(0, cxxNewExpr(hasType(pointsTo(qualType( - equalsBoundNode(PointerType) - .bind(NewExpression))) +hasArgument( +0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType( + equalsBoundNode(PointerType)) + .bind(NewExpression))) .bind(ConstructorCall))), this); } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp?rev=252041&r1=252040&r2=252041&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp Wed Nov 4 04:27:51 2015 @@ -195,3 +195,9 @@ void whitespaces() { // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_unique instead // CHECK-FIXES: auto Spaces = std::make_unique(); } + +void nesting() { + auto Nest = std::unique_ptr>(new std::unique_ptr(new int)); + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_unique instead + // CHECK-FIXES: auto Nest = std::make_unique>(new int); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r252278 - Fix another case where loop-convert wasn't handling correctly data members.
Author: angelgarcia Date: Fri Nov 6 03:59:14 2015 New Revision: 252278 URL: http://llvm.org/viewvc/llvm-project?rev=252278&view=rev Log: Fix another case where loop-convert wasn't handling correctly data members. Summary: If the container expression was obtained from the point where "size" (which usually is a const method) is invoked, then the topmost node in this expression may be an implicit cast to const. When the container is a data member, the check was trying to obtain the member expression directly and was failing in the case mentioned above. This is solved by ignoring implicit casts. Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D14378 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp?rev=252278&r1=252277&r2=252278&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertCheck.cpp Fri Nov 6 03:59:14 2015 @@ -352,12 +352,12 @@ static StringRef getStringFromRange(Sour LangOpts); } -/// \brief If the given expression is actually a DeclRefExpr, find and return -/// the underlying ValueDecl; otherwise, return NULL. +/// \brief If the given expression is actually a DeclRefExpr or a MemberExpr, +/// find and return the underlying ValueDecl; otherwise, return NULL. static const ValueDecl *getReferencedVariable(const Expr *E) { if (const DeclRefExpr *DRE = getDeclRef(E)) return dyn_cast(DRE->getDecl()); - if (const auto *Mem = dyn_cast(E)) + if (const auto *Mem = dyn_cast(E->IgnoreParenImpCasts())) return dyn_cast(Mem->getMemberDecl()); return nullptr; } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp?rev=252278&r1=252277&r2=252278&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Fri Nov 6 03:59:14 2015 @@ -240,6 +240,7 @@ void refs_and_vals() { struct MemberNaming { const static int N = 10; int Ints[N], Ints_[N]; + dependent DInts; void loops() { for (int I = 0; I < N; ++I) { printf("%d\n", Ints[I]); @@ -254,8 +255,32 @@ struct MemberNaming { // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead // CHECK-FIXES: for (int Int : Ints_) // CHECK-FIXES-NEXT: printf("%d\n", Int); + +for (int I = 0; I < DInts.size(); ++I) { + printf("%d\n", DInts[I]); +} +// CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead +// CHECK-FIXES: for (int DInt : DInts) +// CHECK-FIXES-NEXT: printf("%d\n", DInt); } + + void outOfLine(); }; +void MemberNaming::outOfLine() { + for (int I = 0; I < N; ++I) { +printf("%d\n", Ints[I]); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (int Int : Ints) + // CHECK-FIXES-NEXT: printf("%d\n", Int); + + for (int I = 0; I < N; ++I) { +printf("%d\n", Ints_[I]); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (int Int : Ints_) + // CHECK-FIXES-NEXT: printf("%d\n", Int); +} } // namespace NamingAlias ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r252303 - Avoid naming conflicts with the old index in modernize-loop-convert.
Author: angelgarcia Date: Fri Nov 6 08:04:12 2015 New Revision: 252303 URL: http://llvm.org/viewvc/llvm-project?rev=252303&view=rev Log: Avoid naming conflicts with the old index in modernize-loop-convert. Summary: The old index declaration is going to be removed anyway, so we can reuse its name if it is the best candidate for the new index. Reviewers: klimek Subscribers: cfe-commits, alexfh Differential Revision: http://reviews.llvm.org/D14437 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=252303&r1=252302&r2=252303&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Fri Nov 6 08:04:12 2015 @@ -820,14 +820,14 @@ std::string VariableNamer::createIndexNa if (Len > 1 && ContainerName.endswith(Style == NS_UpperCase ? "S" : "s")) { IteratorName = ContainerName.substr(0, Len - 1); // E.g.: (auto thing : things) -if (!declarationExists(IteratorName)) +if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName()) return IteratorName; } if (Len > 2 && ContainerName.endswith(Style == NS_UpperCase ? "S_" : "s_")) { IteratorName = ContainerName.substr(0, Len - 2); // E.g.: (auto thing : things_) -if (!declarationExists(IteratorName)) +if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName()) return IteratorName; } @@ -849,12 +849,12 @@ std::string VariableNamer::createIndexNa IteratorName = AppendWithStyle(ContainerName, OldIndex->getName()); // E.g.: (auto container_i : container) - if (!declarationExists(IteratorName)) + if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName()) return IteratorName; IteratorName = AppendWithStyle(ContainerName, Elem); // E.g.: (auto container_elem : container) - if (!declarationExists(IteratorName)) + if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName()) return IteratorName; // Someone defeated my naming scheme... @@ -875,7 +875,8 @@ std::string VariableNamer::createIndexNa int Attempt = 0; do { IteratorName = GiveMeName + std::to_string(Attempt++); - } while (declarationExists(IteratorName)); + } while (declarationExists(IteratorName) || + IteratorName == OldIndex->getName()); return IteratorName; } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp?rev=252303&r1=252302&r2=252303&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Fri Nov 6 08:04:12 2015 @@ -325,6 +325,23 @@ void sameNames() { // CHECK-FIXES-NEXT: (void)NumsI; } +void oldIndexConflict() { + for (int Num = 0; Num < N; ++Num) { +printf("Num: %d\n", Nums[Num]); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (int Num : Nums) + // CHECK-FIXES-NEXT: printf("Num: %d\n", Num); + + S Things; + for (S::iterator Thing = Things.begin(), End = Things.end(); Thing != End; ++Thing) { +printf("Thing: %d %d\n", Thing->X, (*Thing).X); + } + // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & Thing : Things) + // CHECK-FIXES-NEXT: printf("Thing: %d %d\n", Thing.X, Thing.X); +} + void macroConflict() { S MAXs; for (S::iterator It = MAXs.begin(), E = MAXs.end(); It != E; ++It) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] r252308 - Use the old index identifier by default, instead of 'elem'.
Author: angelgarcia Date: Fri Nov 6 09:03:14 2015 New Revision: 252308 URL: http://llvm.org/viewvc/llvm-project?rev=252308&view=rev Log: Use the old index identifier by default, instead of 'elem'. Summary: Use the old index name in the cases where the check would come up with an invented name. Reviewers: klimek Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D14438 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-camelback.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-const.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-lowercase.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-uppercase.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=252308&r1=252307&r2=252308&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Fri Nov 6 09:03:14 2015 @@ -831,54 +831,7 @@ std::string VariableNamer::createIndexNa return IteratorName; } - std::string Elem; - switch (Style) { - case NS_CamelBack: - case NS_LowerCase: -Elem = "elem"; -break; - case NS_CamelCase: -Elem = "Elem"; -break; - case NS_UpperCase: -Elem = "ELEM"; - } - // E.g.: (auto elem : container) - if (!declarationExists(Elem)) -return Elem; - - IteratorName = AppendWithStyle(ContainerName, OldIndex->getName()); - // E.g.: (auto container_i : container) - if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName()) -return IteratorName; - - IteratorName = AppendWithStyle(ContainerName, Elem); - // E.g.: (auto container_elem : container) - if (!declarationExists(IteratorName) || IteratorName == OldIndex->getName()) -return IteratorName; - - // Someone defeated my naming scheme... - std::string GiveMeName; - switch (Style) { - case NS_CamelBack: -GiveMeName = "giveMeName"; -break; - case NS_CamelCase: -GiveMeName = "GiveMeName"; -break; - case NS_LowerCase: -GiveMeName = "give_me_name_"; -break; - case NS_UpperCase: -GiveMeName = "GIVE_ME_NAME_"; - } - int Attempt = 0; - do { -IteratorName = GiveMeName + std::to_string(Attempt++); - } while (declarationExists(IteratorName) || - IteratorName == OldIndex->getName()); - - return IteratorName; + return OldIndex->getName(); } /// \brief Determines whether or not the the name \a Symbol conflicts with Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp?rev=252308&r1=252307&r2=252308&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-basic.cpp Fri Nov 6 09:03:14 2015 @@ -18,8 +18,8 @@ void f() { int K; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead [modernize-loop-convert] - // CHECK-FIXES: for (int Elem : Arr) - // CHECK-FIXES-NEXT: Sum += Elem; + // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES-NEXT: Sum += I; // CHECK-FIXES-NEXT: int K; for (int I = 0; I < N; ++I) { @@ -27,66 +27,66 @@ void f() { Sum += Arr[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Elem : Arr) - // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", Elem); - // CHECK-FIXES-NEXT: Sum += Elem + 2; + // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I); + // CHECK-FIXES-NEXT: Sum += I + 2; for (int I = 0; I < N; ++I) { int X = Arr[I]; int Y = Arr[I] + 2; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Elem : Arr) - // CHECK-FIXES-NEXT: int X = Elem; - // CHECK-FIXES-NEXT: int Y = Elem + 2; + // CHECK-FIXES: for (int I : Arr) + // CHECK-FIXES-NEXT: int X = I; + // CHECK-FIXES-NEXT: int Y = I + 2; for (int I = 0; I < N; ++I) { int X = N; X = Arr[I]; } // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead - // CHECK-FIXES: for (int Elem : Arr) + // CHECK-FIXES: for (int I : Arr) // CHECK-FIXES-NEXT: int X = N; - // CHECK-FIXES-NEXT: X = Elem; + // CHECK-FIXES-NEXT: X = I; for (int I = 0;
[clang-tools-extra] r252315 - Allow the alias to be of a different type.
Author: angelgarcia Date: Fri Nov 6 09:47:04 2015 New Revision: 252315 URL: http://llvm.org/viewvc/llvm-project?rev=252315&view=rev Log: Allow the alias to be of a different type. Summary: Consider a declaration an alias even if it doesn't have the same unqualified type than the container element, as long as one can be converted to the other using only implicit casts. Reviewers: klimek Subscribers: alexfh, cfe-commits Differential Revision: http://reviews.llvm.org/D14442 Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Modified: clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp?rev=252315&r1=252314&r2=252315&view=diff == --- clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/modernize/LoopConvertUtils.cpp Fri Nov 6 09:47:04 2015 @@ -342,21 +342,27 @@ static bool isAliasDecl(ASTContext *Cont if (!VDecl->hasInit()) return false; - const Expr *Init = - digThroughConstructors(VDecl->getInit()->IgnoreParenImpCasts()); + bool OnlyCasts = true; + const Expr *Init = VDecl->getInit()->IgnoreParenImpCasts(); + if (Init && isa(Init)) { +Init = digThroughConstructors(Init); +OnlyCasts = false; + } if (!Init) return false; // Check that the declared type is the same as (or a reference to) the // container type. - QualType InitType = Init->getType(); - QualType DeclarationType = VDecl->getType(); - if (!DeclarationType.isNull() && DeclarationType->isReferenceType()) -DeclarationType = DeclarationType.getNonReferenceType(); - - if (InitType.isNull() || DeclarationType.isNull() || - !Context->hasSameUnqualifiedType(DeclarationType, InitType)) -return false; + if (!OnlyCasts) { +QualType InitType = Init->getType(); +QualType DeclarationType = VDecl->getType(); +if (!DeclarationType.isNull() && DeclarationType->isReferenceType()) + DeclarationType = DeclarationType.getNonReferenceType(); + +if (InitType.isNull() || DeclarationType.isNull() || +!Context->hasSameUnqualifiedType(DeclarationType, InitType)) + return false; + } switch (Init->getStmtClass()) { case Stmt::ArraySubscriptExprClass: { @@ -384,8 +390,8 @@ static bool isAliasDecl(ASTContext *Cont const auto *MemCall = cast(Init); // This check is needed because getMethodDecl can return nullptr if the // callee is a member function pointer. -if (MemCall->getMethodDecl() && -MemCall->getMethodDecl()->getName() == "at") { +const auto *MDecl = MemCall->getMethodDecl(); +if (MDecl && !isa(MDecl) && MDecl->getName() == "at") { assert(MemCall->getNumArgs() == 1); return isIndexInSubscriptExpr(MemCall->getArg(0), IndexVar); } Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp?rev=252315&r1=252314&r2=252315&view=diff == --- clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/modernize-loop-convert-extra.cpp Fri Nov 6 09:47:04 2015 @@ -159,7 +159,7 @@ void aliasing() { // CHECK-FIXES: for (int Alias : IntArr) // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J) - struct IntRef { IntRef(const int& i); }; + struct IntRef { IntRef(); IntRef(const int& i); operator int*(); }; for (int I = 0; I < N; ++I) { IntRef Int(IntArr[I]); } @@ -167,6 +167,25 @@ void aliasing() { // CHECK-FIXES: for (int I : IntArr) // CHECK-FIXES-NEXT: IntRef Int(I); + int *PtrArr[N]; + for (unsigned I = 0; I < N; ++I) { +const int* const P = PtrArr[I]; +printf("%d\n", *P); + } + // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto P : PtrArr) + // CHECK-FIXES-NEXT: printf("%d\n", *P); + + IntRef Refs[N]; + for (unsigned I = 0; I < N; ++I) { +int *P = Refs[I]; +printf("%d\n", *P); + } + // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead + // CHECK-FIXES: for (auto & Ref : Refs) + // CHECK-FIXES-NEXT: int *P = Ref; + // CHECK-FIXES-NEXT: printf("%d\n", *P); + // Ensure that removing the alias doesn't leave empty lines behind. for (int I = 0; I < N; ++I) { auto &X = IntArr[I]; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits