summaryrefslogtreecommitdiffstats
path: root/tools/clang
diff options
context:
space:
mode:
authorrsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 01:31:24 +0000
committerrsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 01:31:24 +0000
commit7131dba5f6713c9b7958dee8244858704cb5c57a (patch)
treed6e454e003200403e2909d24f06c80c5fbf316aa /tools/clang
parent416f31aa17083fd35610dd3f0daa0a9b67ac4611 (diff)
downloadchromium_src-7131dba5f6713c9b7958dee8244858704cb5c57a.zip
chromium_src-7131dba5f6713c9b7958dee8244858704cb5c57a.tar.gz
chromium_src-7131dba5f6713c9b7958dee8244858704cb5c57a.tar.bz2
Check implementation files for virtual and OVERRIDE.
Currently behind a flag "-Xclang -plugin-arg-find-bad-constructs -Xclang skip-virtuals-in-implementations" BUG=115047 TEST=none Review URL: https://chromiumcodereview.appspot.com/10076002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132507 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/clang')
-rw-r--r--tools/clang/plugins/FindBadConstructs.cpp41
-rw-r--r--tools/clang/plugins/tests/overridden_methods.cpp26
-rw-r--r--tools/clang/plugins/tests/overridden_methods.txt11
-rw-r--r--tools/clang/plugins/tests/virtual_methods.cpp6
-rwxr-xr-xtools/clang/scripts/plugin_flags.sh4
5 files changed, 70 insertions, 18 deletions
diff --git a/tools/clang/plugins/FindBadConstructs.cpp b/tools/clang/plugins/FindBadConstructs.cpp
index 193fc84..fee2aad 100644
--- a/tools/clang/plugins/FindBadConstructs.cpp
+++ b/tools/clang/plugins/FindBadConstructs.cpp
@@ -49,9 +49,11 @@ const Type* UnwrapType(const Type* type) {
class FindBadConstructsConsumer : public ChromeClassTester {
public:
FindBadConstructsConsumer(CompilerInstance& instance,
- bool check_refcounted_dtors)
+ bool check_refcounted_dtors,
+ bool check_virtuals_in_implementations)
: ChromeClassTester(instance),
- check_refcounted_dtors_(check_refcounted_dtors) {
+ check_refcounted_dtors_(check_refcounted_dtors),
+ check_virtuals_in_implementations_(check_virtuals_in_implementations) {
}
virtual void CheckChromeClass(SourceLocation record_location,
@@ -62,10 +64,14 @@ class FindBadConstructsConsumer : public ChromeClassTester {
// Only check for "heavy" constructors/destructors in header files;
// within implementation files, there is no performance cost.
CheckCtorDtorWeight(record_location, record);
+ }
+
+ if (!implementation_file || check_virtuals_in_implementations_) {
+ bool warn_on_inline_bodies = !implementation_file;
// Check that all virtual methods are marked accordingly with both
// virtual and OVERRIDE.
- CheckVirtualMethods(record_location, record);
+ CheckVirtualMethods(record_location, record, warn_on_inline_bodies);
}
if (check_refcounted_dtors_)
@@ -74,6 +80,7 @@ class FindBadConstructsConsumer : public ChromeClassTester {
private:
bool check_refcounted_dtors_;
+ bool check_virtuals_in_implementations_;
// Returns true if |base| specifies one of the Chromium reference counted
// classes (base::RefCounted / base::RefCountedThreadSafe). |user_data| is
@@ -225,7 +232,8 @@ class FindBadConstructsConsumer : public ChromeClassTester {
}
}
- void CheckVirtualMethod(const CXXMethodDecl* method) {
+ void CheckVirtualMethod(const CXXMethodDecl* method,
+ bool warn_on_inline_bodies) {
if (!method->isVirtual())
return;
@@ -236,8 +244,10 @@ class FindBadConstructsConsumer : public ChromeClassTester {
emitWarning(loc, "Overriding method must have \"virtual\" keyword.");
}
- // Virtual methods should not have inline definitions beyond "{}".
- if (method->hasBody() && method->hasInlineBody()) {
+ // Virtual methods should not have inline definitions beyond "{}". This
+ // only matters for header files.
+ if (warn_on_inline_bodies && method->hasBody() &&
+ method->hasInlineBody()) {
if (CompoundStmt* cs = dyn_cast<CompoundStmt>(method->getBody())) {
if (cs->size()) {
emitWarning(
@@ -281,15 +291,15 @@ class FindBadConstructsConsumer : public ChromeClassTester {
emitWarning(loc, "Overriding method must be marked with OVERRIDE.");
}
- // Makes sure there is a "virtual" keyword on virtual methods and that there
- // are no inline function bodies on them (but "{}" is allowed).
+ // Makes sure there is a "virtual" keyword on virtual methods.
//
// Gmock objects trigger these for each MOCK_BLAH() macro used. So we have a
// trick to get around that. If a class has member variables whose types are
// in the "testing" namespace (which is how gmock works behind the scenes),
// there's a really high chance we won't care about these errors
void CheckVirtualMethods(SourceLocation record_location,
- CXXRecordDecl* record) {
+ CXXRecordDecl* record,
+ bool warn_on_inline_bodies) {
for (CXXRecordDecl::field_iterator it = record->field_begin();
it != record->field_end(); ++it) {
CXXRecordDecl* record_type =
@@ -310,7 +320,7 @@ class FindBadConstructsConsumer : public ChromeClassTester {
!record->hasUserDeclaredDestructor()) {
// Ignore non-user-declared destructors.
} else {
- CheckVirtualMethod(*it);
+ CheckVirtualMethod(*it, warn_on_inline_bodies);
CheckOverriddenMethod(*it);
}
}
@@ -376,11 +386,15 @@ class FindBadConstructsConsumer : public ChromeClassTester {
class FindBadConstructsAction : public PluginASTAction {
public:
- FindBadConstructsAction() : check_refcounted_dtors_(true) {}
+ FindBadConstructsAction()
+ : check_refcounted_dtors_(true),
+ check_virtuals_in_implementations_(true) {
+ }
protected:
ASTConsumer* CreateASTConsumer(CompilerInstance &CI, llvm::StringRef ref) {
- return new FindBadConstructsConsumer(CI, check_refcounted_dtors_);
+ return new FindBadConstructsConsumer(
+ CI, check_refcounted_dtors_, check_virtuals_in_implementations_);
}
bool ParseArgs(const CompilerInstance &CI,
@@ -390,6 +404,8 @@ class FindBadConstructsAction : public PluginASTAction {
for (size_t i = 0; i < args.size() && parsed; ++i) {
if (args[i] == "skip-refcounted-dtors") {
check_refcounted_dtors_ = false;
+ } else if (args[i] == "skip-virtuals-in-implementations") {
+ check_virtuals_in_implementations_ = false;
} else {
parsed = false;
llvm::errs() << "Unknown argument: " << args[i] << "\n";
@@ -401,6 +417,7 @@ class FindBadConstructsAction : public PluginASTAction {
private:
bool check_refcounted_dtors_;
+ bool check_virtuals_in_implementations_;
};
} // namespace
diff --git a/tools/clang/plugins/tests/overridden_methods.cpp b/tools/clang/plugins/tests/overridden_methods.cpp
index f81d3a2..f572a41 100644
--- a/tools/clang/plugins/tests/overridden_methods.cpp
+++ b/tools/clang/plugins/tests/overridden_methods.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,6 +9,30 @@ void DerivedClass::SomeMethod() {}
void DerivedClass::SomeOtherMethod() {}
void DerivedClass::WebKitModifiedSomething() {}
+class ImplementationInterimClass : public BaseClass {
+ public:
+ // Should not warn about pure virtual methods.
+ virtual void SomeMethod() = 0;
+};
+
+class ImplementationDerivedClass : public ImplementationInterimClass,
+ public webkit_glue::WebKitObserverImpl {
+ public:
+ // Should not warn about destructors.
+ virtual ~ImplementationDerivedClass() {}
+ // Should warn.
+ virtual void SomeMethod();
+ // Should not warn if marked as override.
+ virtual void SomeOtherMethod() override;
+ // Should not warn for inline implementations in implementation files.
+ virtual void SomeInlineMethod() {}
+ // Should not warn if overriding a method whose origin is WebKit.
+ virtual void WebKitModifiedSomething();
+ // Should warn if overridden method isn't pure.
+ virtual void SomeNonPureBaseMethod() {}
+};
+
int main() {
DerivedClass something;
+ ImplementationDerivedClass something_else;
}
diff --git a/tools/clang/plugins/tests/overridden_methods.txt b/tools/clang/plugins/tests/overridden_methods.txt
index a405d31..7553ade 100644
--- a/tools/clang/plugins/tests/overridden_methods.txt
+++ b/tools/clang/plugins/tests/overridden_methods.txt
@@ -8,4 +8,13 @@ In file included from overridden_methods.cpp:5:
./overridden_methods.h:51:11: warning: [chromium-style] Overriding method must be marked with OVERRIDE.
virtual void SomeNonPureBaseMethod() {}
^
-3 warnings generated.
+overridden_methods.cpp:24:11: warning: [chromium-style] Overriding method must be marked with OVERRIDE.
+ virtual void SomeMethod();
+ ^
+overridden_methods.cpp:28:11: warning: [chromium-style] Overriding method must be marked with OVERRIDE.
+ virtual void SomeInlineMethod() {}
+ ^
+overridden_methods.cpp:32:11: warning: [chromium-style] Overriding method must be marked with OVERRIDE.
+ virtual void SomeNonPureBaseMethod() {}
+ ^
+6 warnings generated.
diff --git a/tools/clang/plugins/tests/virtual_methods.cpp b/tools/clang/plugins/tests/virtual_methods.cpp
index 05515b7..a07cbe48 100644
--- a/tools/clang/plugins/tests/virtual_methods.cpp
+++ b/tools/clang/plugins/tests/virtual_methods.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -16,13 +16,13 @@ class VirtualMethodsInImplementation {
// Stubs to fill in the abstract method
class ConcreteVirtualMethodsInHeaders : public VirtualMethodsInHeaders {
public:
- virtual void MethodIsAbstract() {}
+ virtual void MethodIsAbstract() override {}
};
class ConcreteVirtualMethodsInImplementation
: public VirtualMethodsInImplementation {
public:
- virtual void MethodIsAbstract() {}
+ virtual void MethodIsAbstract() override {}
};
// Fill in the implementations
diff --git a/tools/clang/scripts/plugin_flags.sh b/tools/clang/scripts/plugin_flags.sh
index bd9f547..da0ec65 100755
--- a/tools/clang/scripts/plugin_flags.sh
+++ b/tools/clang/scripts/plugin_flags.sh
@@ -18,4 +18,6 @@ fi
echo -Xclang -load -Xclang $CLANG_LIB_PATH/libFindBadConstructs.$LIBSUFFIX \
-Xclang -add-plugin -Xclang find-bad-constructs \
- -Xclang -plugin-arg-find-bad-constructs -Xclang skip-refcounted-dtors
+ -Xclang -plugin-arg-find-bad-constructs -Xclang skip-refcounted-dtors \
+ -Xclang -plugin-arg-find-bad-constructs \
+ -Xclang skip-virtuals-in-implementations