summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2015-01-07 10:40:53 +0200
committerMichael Meeks <michael.meeks@collabora.com>2015-04-09 19:57:44 +0100
commit09b4246c6aa5e75c89df2961816b0124fea7fd78 (patch)
tree7e31b61d514769018f9455a8a189a5e14df1a72e /compilerplugins
parenta632fa5f2e059642f0feffb200e8c9a71ee75802 (diff)
vcl: vclwidget plugin should look for raw vcl::Window usage
teach the vclwidget plugin to look for places where we need to use VclPtr<T> instead of raw pointers Change-Id: I444836bf8e3d05fca0f30380c91a8ce24d1e9d1c
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/vclwidgets.cxx87
1 files changed, 75 insertions, 12 deletions
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx
index faffbada80c8..db4093f13bd2 100644
--- a/compilerplugins/clang/vclwidgets.cxx
+++ b/compilerplugins/clang/vclwidgets.cxx
@@ -33,16 +33,29 @@ public:
bool VisitFieldDecl(const FieldDecl * decl);
- bool mbFoundWindow;
+ bool VisitParmVarDecl(ParmVarDecl const * decl);
+
+ bool VisitVarDecl( const VarDecl* var );
+
};
-bool forallBasesCallback(const CXXBaseSpecifier *Specifier, CXXBasePath &, void *UserData) {
- VCLWidgets* ro = (VCLWidgets*) UserData;
- QualType qt = Specifier->getType();
- std::string name = qt.getUnqualifiedType().getCanonicalType().getAsString();
- if (name == "class Window") {
- ro->mbFoundWindow = true;
- return true;
+bool BaseCheckNotWindowSubclass(const CXXRecordDecl *BaseDefinition, void *) {
+ if (BaseDefinition->getQualifiedNameAsString().compare("vcl::Window") == 0) {
+ return false;
+ }
+ return true;
+}
+
+bool isDerivedFromWindow(const CXXRecordDecl *decl) {
+ if (!decl->hasDefinition())
+ return false;
+ if (decl->getQualifiedNameAsString().compare("vcl::Window") == 0)
+ return true;
+ if (// not sure what hasAnyDependentBases() does,
+ // but it avoids classes we don't want, e.g. WeakAggComponentImplHelper1
+ !decl->hasAnyDependentBases() &&
+ !decl->forallBases(BaseCheckNotWindowSubclass, nullptr, true)) {
+ return true;
}
return false;
}
@@ -63,10 +76,7 @@ bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
return true;
}
// check if this field is derived from Window
- mbFoundWindow = false;
- CXXBasePaths paths;
- recordDecl->lookupInBases(forallBasesCallback, this, paths);
- if (!mbFoundWindow) {
+ if (!isDerivedFromWindow(recordDecl)) {
return true;
}
@@ -78,6 +88,59 @@ bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
return true;
}
+bool VCLWidgets::VisitParmVarDecl(ParmVarDecl const * pvDecl) {
+ if (ignoreLocation(pvDecl)) {
+ return true;
+ }
+ if (!pvDecl->getType()->isPointerType())
+ return true;
+ QualType pointeeType = pvDecl->getType()->getPointeeType();
+ const RecordType *recordType = pointeeType->getAs<RecordType>();
+ if (recordType == nullptr)
+ return true;
+ const CXXRecordDecl *recordDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl());
+ if (recordDecl == nullptr)
+ return true;
+
+ // check if this parameter is derived from Window
+ if (isDerivedFromWindow(recordDecl)) {
+ report(
+ DiagnosticsEngine::Remark,
+ "vcl::Window subclass passed as a pointer parameter, should be wrapped in VclPtr.",
+ pvDecl->getLocation())
+ << pvDecl->getSourceRange();
+ }
+ return true;
+}
+
+bool VCLWidgets::VisitVarDecl( const VarDecl* varDecl )
+{
+ if (ignoreLocation(varDecl)) {
+ return true;
+ }
+ if (!varDecl->isLocalVarDecl())
+ return true;
+ if (!varDecl->getType()->isPointerType())
+ return true;
+ QualType pointeeType = varDecl->getType()->getPointeeType();
+ const RecordType *recordType = pointeeType->getAs<RecordType>();
+ if (recordType == nullptr)
+ return true;
+ const CXXRecordDecl *recordDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl());
+ if (recordDecl == nullptr)
+ return true;
+
+ // check if this variables type is derived from Window
+ if (isDerivedFromWindow(recordDecl)) {
+ report(
+ DiagnosticsEngine::Remark,
+ "vcl::Window subclass declared as a pointer var, should be wrapped in VclPtr.",
+ varDecl->getLocation())
+ << varDecl->getSourceRange();
+ }
+
+ return true;
+}
loplugin::Plugin::Registration< VCLWidgets > X("vclwidgets");