[PATCH] D27621: [clang-tidy] check to find declarations declaring more than one name
Firat Kasmis via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 23 05:19:09 PST 2016
firolino marked 18 inline comments as done.
firolino added a comment.
Addressed suggestions from @aaron.ballman Thanks!
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:22
+
+const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl;
+
----------------
aaron.ballman wrote:
> We may want to consider adding this to ASTMatchers.h at some point (can be done in a future patch).
Is there a `// FIXME: Once I am in AstMatcher.h, remove me.` OK?
================
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,
----------------
aaron.ballman wrote:
> This should accept by `const std::string &`.
Since I need a copy, it is more efficient to pass-by-value instead pass-by-reference + copy. So, I get a benefit for rvalues and move will be applied. Search for "want speed? pass by value!" articles.
================
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(
----------------
aaron.ballman wrote:
> Why do we not want to match this?
If we decide, whether we transform
```
class A {
} Object1, Object2;
```
to
```
class A {
} Object1,
Object2;
```
or
```
class A {
}
Object1,
Object2;
```
I might consider adding support for it. Moreover, this kind of definition is usually seen globally and I don't know how to handle globals yet. See http://lists.llvm.org/pipermail/cfe-dev/2015-November/046262.html
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:53
+ const LangOptions &LangOpts = getLangOpts();
+ const auto DeclGroup = DeclStatement->getDeclGroup();
+
----------------
aaron.ballman wrote:
> 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.
Alright. What about:
```
const auto FirstVarIt = DeclStmt->getDeclGroup().begin();
const auto DL = SM.getDecomposedLoc(Loc);
```
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:61
+ DeclStmtStart,
+ "declaration statement can be split up into single line declarations");
+
----------------
aaron.ballman wrote:
> 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?
Yes. Sounds better.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:83
+ if (AnyTokenBetweenCommaAndVarName.front() == '#')
+ AnyTokenBetweenCommaAndVarName.insert(0, "\n");
+
----------------
aaron.ballman wrote:
> Will this (and the below `\n`) be converted into a CRLF automatically on platforms where that is the newline character sequence in the source?
Actually, I was thinking about this but I don't have a Windows etc. with a running llvm environment. Is it OK, if I leave a FIXME for now?
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:101
+ QualType Type;
+ if (const auto *FirstVar = dyn_cast<const DeclaratorDecl>(*FirstVarIt)) {
+ Location = FirstVar->getLocation();
----------------
aaron.ballman wrote:
> You can drop the `const` from the `dyn_cast`, here and elsewhere.
Alright, but can you explain why?
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:107
+ Type = FirstVar->getTypeSourceInfo()->getType();
+ while (Type->isLValueReferenceType()) {
+ Type = Type->getPointeeType();
----------------
aaron.ballman wrote:
> Why references and not pointers? Perhaps this needs a comment.
`// Typedefs on function pointers are covered into LValueReferenceType's` ?
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:137
+ while (Type->isAnyPointerType() || Type->isArrayType())
+ Type = Type->getPointeeOrArrayElementType()->getCanonicalTypeInternal();
+ }
----------------
aaron.ballman wrote:
> Why are you calling the Internal version of this function?
Because I need its QualType.
================
Comment at: clang-tidy/readability/OneNamePerDeclarationCheck.cpp:160
+
+static bool isWhitespaceExceptNL(unsigned char C) {
+ switch (C) {
----------------
aaron.ballman wrote:
> 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`?
CharInfo, nice! `unsigned char` because there is no negative ASCII. Even isWhitespace has `unsigned char`.
================
Comment at: clang-tidy/readability/ReadabilityTidyModule.cpp:64
+ CheckFactories.registerCheck<OneNamePerDeclarationCheck>(
+ "readability-one-name-per-declaration");
CheckFactories.registerCheck<RedundantMemberInitCheck>(
----------------
aaron.ballman wrote:
> 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?
I will include Options for these checks in the future, since they have special rules when to split a declaration. See https://reviews.llvm.org/D25024#inline-221483
https://reviews.llvm.org/D27621
More information about the cfe-commits
mailing list