[PATCH] D15710: [clang-tidy] Add non-inline function definition and variable definition check in header files.
Alexander Kornienko via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 22 07:42:38 PST 2015
alexfh added inline comments.
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.cpp:23
@@ +22,3 @@
+bool inHeaderFile(const SourceManager* SM,
+ const SourceLocation& Location) {
+ StringRef Filename = SM->getFilename(SM->getExpansionLoc(Location));
----------------
`SourceLocations` are small and trivially-copyable, they should be passed by value.
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.cpp:31
@@ +30,3 @@
+void DefinitionsInHeadersCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(functionDecl(isDefinition()).bind("fun-definition"), this);
+ Finder->addMatcher(varDecl(isDefinition()).bind("var-definition"), this);
----------------
I'd use a single matcher for both functions and variables (`decl(anyOf(functionDecl(), varDecl()), isDefinition()).bind("decl")`) to avoid duplicating code in the callback.
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.cpp:42
@@ +41,3 @@
+ // appears in a different translation unit, and provided the definitions
+ // satisfy the following requirements. (C++ basic.def.odr)
+ if (auto funDecl = Result.Nodes.getNodeAs<FunctionDecl>("fun-definition")) {
----------------
Please put the `C++ [basic.def.odr]:` part before the quotation from the standard.
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.cpp:43
@@ +42,3 @@
+ // satisfy the following requirements. (C++ basic.def.odr)
+ if (auto funDecl = Result.Nodes.getNodeAs<FunctionDecl>("fun-definition")) {
+ if (!inHeaderFile(Result.SourceManager, funDecl->getLocStart()))
----------------
Please use `const auto *` to make it clear that this is a pointer. Same elsewhere.
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.cpp:52
@@ +51,3 @@
+ // Inline function is allowed.
+ if (funDecl->isInlined())
+ return;
----------------
This check can be done in the matcher.
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.cpp:62
@@ +61,3 @@
+ if (auto cxxMethodDecl = dyn_cast<CXXMethodDecl>(funDecl)) {
+ if (cxxMethodDecl->getParent()->getDescribedClassTemplate()) {
+ return;
----------------
nit: No braces needed here.
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.cpp:68
@@ +67,3 @@
+ diag(funDecl->getLocation(),
+ "function definition is not allowed in header file.")
+ << FixItHint::CreateInsertion(funDecl->getSourceRange().getBegin(),
----------------
Warning messages are not full sentences. No trailing period is needed.
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.h:17
@@ +16,3 @@
+namespace tidy {
+namespace google {
+
----------------
This check is generic enough. It should go to the `misc` module, IMO.
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.h:19
@@ +18,3 @@
+
+// Finds non-inline function definition and variable definition in headers,
+// which may violate cpp one definition rule.
----------------
This would read slightly better: "Finds non-extern non-inline function and variable definitions in header files, which can lead to ODR violations."
================
Comment at: clang-tidy/google/DefinitionsInHeadersCheck.h:20
@@ +19,3 @@
+// Finds non-inline function definition and variable definition in headers,
+// which may violate cpp one definition rule.
+class DefinitionsInHeadersCheck : public ClangTidyCheck {
----------------
Please add a link to the user-facing documentation:
// For the user-facing documentation see:
// http://clang.llvm.org/extra/clang-tidy/checks/<check-name>.html
================
Comment at: docs/clang-tidy/checks/google-definitions-in-headers.rst:4
@@ +3,3 @@
+
+Finds non-inline function definition and variable definition in headers, which
+may violate cpp one definition rule.
----------------
Please update the wording to match the class comment, and also add a couple of examples of what cases does the check detect.
================
Comment at: unittests/clang-tidy/GoogleModuleTest.cpp:140
@@ +139,3 @@
+ "}", "foo.h"));
+ EXPECT_EQ(errorMessage, runCheckOnCode("template <typename T>\n"
+ "T f() {\n"
----------------
I think, we can already use raw string literals (at least, MSVC 2013 seems to support them). Raw string literals would make the test cases more readable, imo.
Repository:
rL LLVM
http://reviews.llvm.org/D15710
More information about the cfe-commits
mailing list