diff options
author | Noel Grandin <noel@peralex.com> | 2015-01-07 10:40:53 +0200 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-04-09 19:57:44 +0100 |
commit | 09b4246c6aa5e75c89df2961816b0124fea7fd78 (patch) | |
tree | 7e31b61d514769018f9455a8a189a5e14df1a72e /compilerplugins | |
parent | a632fa5f2e059642f0feffb200e8c9a71ee75802 (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.cxx | 87 |
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"); |