[PATCH] D27621: [clang-tidy] check to find declarations declaring more than one name
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 19 12:36:37 PST 2016
aaron.ballman added inline comments.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:22
+
+const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl;
+
----------------
We may want to consider adding this to ASTMatchers.h at some point (can be done in a future patch).
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:25
+static bool isWhitespaceExceptNL(unsigned char C);
+static std::string removeMultiLineComments(std::string Str);
+static std::string getCurrentLineIndent(SourceLocation Loc,
----------------
This should accept by `const std::string &`.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:32
+ // Matches all non-single declaration within a compound statement {...}.
+ // Unless, the variable declaration is a object definition directly after
+ // a tag declaration (e.g. struct, class etc.):
----------------
is a object -> is an object
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:34
+ // a tag declaration (e.g. struct, class etc.):
+ // class A { } Object1, Object2; <-- won't be matched
+ Finder->addMatcher(
----------------
Why do we not want to match this?
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:44
+ const auto *DeclStatement = Result.Nodes.getNodeAs<DeclStmt>("declstmt");
+ if (DeclStatement == nullptr)
+ return;
----------------
No need to compare against nullptr explicitly (I think we have a clang-tidy check that will warn on this, in fact).
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:53
+ const LangOptions &LangOpts = getLangOpts();
+ const auto DeclGroup = DeclStatement->getDeclGroup();
+
----------------
Please don't use `auto` as the type is not spelled out explicitly in the initialization. Same elsewhere, though it is fine with `diag()` and in for loop initializers.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:61
+ DeclStmtStart,
+ "declaration statement can be split up into single line declarations");
+
----------------
This reads a bit awkwardly since it doesn't explain why the code is problematic. Perhaps: "multiple declarations should be split into individual declarations to improve readability" or something like that?
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:67
+ for (auto It = DeclGroup.begin() + 1; It != DeclGroup.end(); ++It) {
+
+ const auto NameLocation = dyn_cast<const NamedDecl>(*It)->getLocation();
----------------
No need for the newline.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:81
+
+ // Check for pre-processor directive and add appropriate newline
+ if (AnyTokenBetweenCommaAndVarName.front() == '#')
----------------
Missing a full stop at the end of the sentence. Also, no hyphen in preprocessor, and it should be "add an appropriate".
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:83
+ if (AnyTokenBetweenCommaAndVarName.front() == '#')
+ AnyTokenBetweenCommaAndVarName.insert(0, "\n");
+
----------------
Will this (and the below `\n`) be converted into a CRLF automatically on platforms where that is the newline character sequence in the source?
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:87
+ << FixItHint::CreateReplacement(AfterCommaToVarNameRange,
+ "\n" + CurrentIndent +
+ UserWrittenType + " " +
----------------
This should probably use a `Twine` to avoid a bunch of copies.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:101
+ QualType Type;
+ if (const auto *FirstVar = dyn_cast<const DeclaratorDecl>(*FirstVarIt)) {
+ Location = FirstVar->getLocation();
----------------
You can drop the `const` from the `dyn_cast`, here and elsewhere.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:107
+ Type = FirstVar->getTypeSourceInfo()->getType();
+ while (Type->isLValueReferenceType()) {
+ Type = Type->getPointeeType();
----------------
Why references and not pointers? Perhaps this needs a comment.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:131
+ Type->isFunctionPointerType() || Type->isFunctionProtoType()) {
+ Pos = UserWrittenType.find_first_of("&*(");
+ if (Pos != std::string::npos) { // might be hidden behind typedef etc.
----------------
You may want to include tests for pathological code, like:
```
int *(i), (*j), (((k)));
```
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:132
+ Pos = UserWrittenType.find_first_of("&*(");
+ if (Pos != std::string::npos) { // might be hidden behind typedef etc.
+ UserWrittenType.erase(Pos);
----------------
`m` should be capitalized, and you can elide the braces.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:137
+ while (Type->isAnyPointerType() || Type->isArrayType())
+ Type = Type->getPointeeOrArrayElementType()->getCanonicalTypeInternal();
+ }
----------------
Why are you calling the Internal version of this function?
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:148
+ Pos != std::string::npos) {
+ // user might have inserted additional whitespaces:
+ // int S ::
----------------
Capitalize "u".
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:160
+
+static bool isWhitespaceExceptNL(unsigned char C) {
+ switch (C) {
----------------
Instead of adding yet another custom check for whether something is whitespace, can you use `isWhitespace()` from CharInfo.h, and special case `\n`? Also, why `unsigned char` instead of `char`?
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:200
+ StringRef IndentSpace;
+ {
+ size_t i = LineOffs;
----------------
Why the extra compound statement?
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:201
+ {
+ size_t i = LineOffs;
+ while (isWhitespaceExceptNL(MB[i])) {
----------------
Should be `I` instead of `i`.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:246
+
+static std::string getCurrentLineIndent(SourceLocation Loc,
+ const SourceManager &SM) {
----------------
firolino wrote:
> malcolm.parsons wrote:
> > Should checks care about formatting, or leave to clang-format?
> At least, they should not change the formatting and try to preserve it. The user shouldn't be forced to run clang-format multiple times. Moreover, not everyone is using clang-format etc.
>
> Having:
> ```
> const int myvalue( 42 ), value ( 4 );
>
> {
> int a, b, c;
> }
> ```
> and getting:
> ```
> const int myvalue(42);
> const int value(4);
>
> {
> int a;
> int b;
> int c;
> }
> ```
> seems very unsatisfying to me. This would force a non-formatting-tool user to start using one.
I think what @malcolm.parsons was getting at is that we have talked about automatically running clang-format over changes made from the FixIt engine instead of trying to add custom logic to all of the places we use FixIts.
================
Comment at: clang-tidy/readability/ReadabilityTidyModule.cpp:64
+ CheckFactories.registerCheck<OneNamePerDeclarationCheck>(
+ "readability-one-name-per-declaration");
CheckFactories.registerCheck<RedundantMemberInitCheck>(
----------------
Should this also be registered as an alias for cert-dcl04-c and CppCoreGuideline ES.10, or is there work left to be done for those checks?
================
Comment at: clang-tidy/utils/LexerUtils.h:15
#include "clang/Lex/Lexer.h"
+#include <vector>
----------------
Please remove this include.
================
Comment at: docs/ReleaseNotes.rst:142
+
+ Finds declarations declaring more that one name.
+
----------------
that -> than
================
Comment at: docs/clang-tidy/checks/readability-one-name-per-declaration.rst:6
+
+This check can be used to find declarations, which declare more than one name.
+It helps improving readability and prevents potential bugs caused by inattention
----------------
Remove the comma. which -> that.
================
Comment at: docs/clang-tidy/checks/readability-one-name-per-declaration.rst:7
+This check can be used to find declarations, which declare more than one name.
+It helps improving readability and prevents potential bugs caused by inattention
+and C/C++ syntax specifics.
----------------
improving -> improve
================
Comment at: test/clang-tidy/readability-one-name-per-declaration-complex.cpp:244
+}
+
----------------
Can you add a test with:
```
template <typename A, typename B> // Should not be touched
void f(A, B);
```
https://reviews.llvm.org/D27621
More information about the cfe-commits
mailing list