This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] Fix llvm-namespace-comment for macro expansions
ClosedPublic

Authored by twardakm on Nov 5 2019, 9:34 AM.

Details

Summary

If a namespace is a macro name, it should be allowed to close the
namespace with the same name.

This commit adds also unit tests for llvm-namespace-comment.

https://bugs.llvm.org/show_bug.cgi?id=26274

Event Timeline

twardakm created this revision.Nov 5 2019, 9:34 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 5 2019, 9:34 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
twardakm edited the summary of this revision. (Show Details)Nov 5 2019, 9:41 AM
twardakm added a project: Restricted Project.
twardakm added a subscriber: twardakm.
Eugene.Zelenko retitled this revision from Fix llvm-namespace-comment for macro expansions to [clang-tidy] Fix llvm-namespace-comment for macro expansions.Nov 5 2019, 11:26 AM
Eugene.Zelenko added inline comments.
clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
253

Is this empty line necessary?

twardakm updated this revision to Diff 228088.Nov 6 2019, 9:46 AM

Remove unnecessary line

twardakm marked an inline comment as done.Nov 6 2019, 9:48 AM

There's a design question about why it should accept the expanded macro name instead of requiring the user to write the macro. I am worried about allowing the expanded form because the presumable use of a macro is to control the name, so this invites name mismatches in other configuration modes.

clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
30

Missing full stop.

32

You can drop the latter const (we don't do top-level const qualification with any consistency).

50–51

You only need to add the macro name in this case, not its value, which should simplify this code considerably.

83

Rather than making an entire new object for PP callbacks, why not make NamespaceCommentCheck inherit from PPCallbacks? It seems like it would simplify the interface somewhat.

245–252

Rather than this, I'd suggest using llvm::any_of().

clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h
50

Missing a full stop at the end of the sentence.

51

I think a better approach is to use a set of some sort because the value of the macro is never used in the check. Probably a SmallPtrSet over StringRef.

clang-tools-extra/test/clang-tidy/checkers/llvm-namespace-comment.cpp
20

This seems unintuitive to me -- it should suggest the macro name instead.

28

This also seems unintuitive to me, I would have wanted this to diagnose and provide a fixit for suggesting the macro name, not its expansion.

twardakm updated this revision to Diff 230113.Nov 19 2019, 11:23 AM

Apply Aaron's comments

  • Fix missing namespace to macro definition instead of extension
  • Print macro definition also in warning message
twardakm marked 9 inline comments as done.Nov 19 2019, 11:32 AM

Thanks for the review!

@aaron.ballman take a look at new revision and let me know if something needs to be fixed. Thanks!

clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
50–51

See comment above, now both value and definition is used

83

I think the check hast to inherit from ClangTidyCheck?

I duplicated the solution from other checks (e.g. IdentifierNamingCheck.cpp). Could you please point to some existing check which implements your idea?

clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.h
51

After applying other comments, both value and definition is used, therefore I stayed with pair of strings. Let me know if you think this comment is still valid

aaron.ballman added inline comments.Nov 20 2019, 6:55 AM
clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
83

I don't know if we have other checks doing this -- I was thinking of using multiple inheritance in this case, because the callbacks are effectively a mixin.

That said, I don't insist on this change.

101–104

Would this work instead Fix.append(" ").append(IsNamespaceMacroExpansion ? MacroDefinition : ND->getName());?

(You may have to check the behavioral difference of getName() vs getNameAsString() to be sure.)

133

llvm::find_if(Macros, ...);

245

Can elide braces.

284

Elide braces

twardakm updated this revision to Diff 230285.Nov 20 2019, 9:44 AM

Fix style issues

twardakm marked 9 inline comments as done.Nov 20 2019, 9:48 AM
twardakm added inline comments.
clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
83

The problem which I see is that addPPCallbacks takes ownership of the object passed to it. I couldn't find any other way of invoking PP callbacks, so I'll leave it as is.

aaron.ballman accepted this revision.Nov 20 2019, 11:08 AM
aaron.ballman marked an inline comment as done.

LGTM!

clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp
83

Ah, that makes sense. Thank you for investigating it. :-)

This revision is now accepted and ready to land.Nov 20 2019, 11:08 AM
twardakm marked an inline comment as done.Nov 20 2019, 1:12 PM

@aaron.ballman thanks for the review :) Can you please push the change on my behalf? I don't have commit rights.

@aaron.ballman thanks for the review :) Can you please push the change on my behalf? I don't have commit rights.

I've commit on your behalf in 4736d63f752f8d13f4c6a9afd558565c32119718, thank you for the patch!

alexfh added a comment.Dec 3 2019, 7:26 AM

There's a problem with this patch. Consider the following code:

// In some remote header:
#define SOME_RANDOM_MACRO internal

// In a completely unrelated file that transitively includes the header:
namespace internal {
void f();
} // namespace internal

It makes the check think that every namespace named internal has something to do with SOME_RANDOM_MACRO.

$ clang_tidy -checks=-*,llvm-* /tmp/q.cc --
1 warning generated.
/tmp/q.cc:7:2: warning: namespace 'SOME_RANDOM_MACRO' ends with a comment that refers to an expansion of macro [llvm-namespace-comment]
} // namespace internal
 ^~~~~~~~~~~~~~~~~~~~~~
  // namespace SOME_RANDOM_MACRO
/tmp/q.cc:5:11: note: namespace 'SOME_RANDOM_MACRO' starts here
namespace internal {
          ^

This is definitely wrong and it introduces tons of false positives in our code. It seems to me that the check shouldn't look any further than what is actually spelled in the namespace declaration. It shouldn't try to match macros to their expansions or vice versa. I'll see whether I can implement this quickly, otherwise I'll just revert this patch to unbreak the checker.

@twardakm: I'm not convinced this feature is worth implementing at all, because there's a good alternative to a macro here -- a namespace alias. What is the reason to use a macro instead of a namespace alias?

The reason for this whole patch was a bug in clang-tidy, which caused warning in the following code:

#define SOME_RANDOM_MACRO macro

namespace SOME_RANDOM_MACRO {

} // namespace SOME_RANDOM_MACRO

and clang-tidy suggested:

namespace SOME_RANDOM_MACRO {

} // namespace macro

which is obviously wrong.

During review we decided that it would be a good idea (apparently not so good) to detect macro expansions and force users to use only macro definitions. This could be useful to avoid mixing macro definitions with macro expansions.

@alexfh, @gribozavr2, @aaron.ballman I think the best way out here is just to implement the basic fix for the above problem and only allow to use macro definition in closing comment and skip checking macro expansions completely. If you agree I will provide a patch for that.

@alexfh, @gribozavr2, @aaron.ballman I think the best way out here is just to implement the basic fix for the above problem and only allow to use macro definition in closing comment and skip checking macro expansions completely. If you agree I will provide a patch for that.

alexfh already provided a fix, please review and ensure that it fixes your case: https://reviews.llvm.org/D70974