summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2015-01-08 13:30:36 +0200
committerMichael Meeks <michael.meeks@collabora.com>2015-04-09 20:03:18 +0100
commita6acccc6d2e6a49691d2612af9898e4018c68861 (patch)
tree790ed2c32a4576f332c6223426c061c12ca65f43 /compilerplugins
parente1d413b132fd7dfa2ea81a1dddf54bcae346db6e (diff)
clang plugin: check return types for vcl::Window* that should be wrapped
Change-Id: I7121c1727d1374a955fbccb6554aede468d4977f
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/vclwidgets.cxx66
1 files changed, 45 insertions, 21 deletions
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx
index db4093f13bd2..aa2af7fe5962 100644
--- a/compilerplugins/clang/vclwidgets.cxx
+++ b/compilerplugins/clang/vclwidgets.cxx
@@ -37,6 +37,7 @@ public:
bool VisitVarDecl( const VarDecl* var );
+ bool VisitFunctionDecl( const FunctionDecl* var );
};
bool BaseCheckNotWindowSubclass(const CXXRecordDecl *BaseDefinition, void *) {
@@ -60,6 +61,21 @@ bool isDerivedFromWindow(const CXXRecordDecl *decl) {
return false;
}
+bool isPointerToWindowSubclass(const QualType& pType) {
+ if (!pType->isPointerType())
+ return false;
+ QualType pointeeType = pType->getPointeeType();
+ const RecordType *recordType = pointeeType->getAs<RecordType>();
+ if (recordType == nullptr) {
+ return false;
+ }
+ const CXXRecordDecl *recordDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl());
+ if (recordDecl == nullptr) {
+ return false;
+ }
+ return isDerivedFromWindow(recordDecl);
+}
+
bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
if (ignoreLocation(fieldDecl)) {
return true;
@@ -67,6 +83,15 @@ bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
if (fieldDecl->isBitField()) {
return true;
}
+ if (isPointerToWindowSubclass(fieldDecl->getType())) {
+ report(
+ DiagnosticsEngine::Remark,
+ "vcl::Window subclass declared as a pointer field, should be wrapped in VclPtr.",
+ fieldDecl->getLocation())
+ << fieldDecl->getSourceRange();
+ return true;
+ }
+
const RecordType *recordType = fieldDecl->getType()->getAs<RecordType>();
if (recordType == nullptr) {
return true;
@@ -92,18 +117,8 @@ 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)) {
+ if (isPointerToWindowSubclass(pvDecl->getType())) {
report(
DiagnosticsEngine::Remark,
"vcl::Window subclass passed as a pointer parameter, should be wrapped in VclPtr.",
@@ -120,18 +135,9 @@ bool VCLWidgets::VisitVarDecl( const VarDecl* varDecl )
}
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)) {
+ if (isPointerToWindowSubclass(varDecl->getType())) {
report(
DiagnosticsEngine::Remark,
"vcl::Window subclass declared as a pointer var, should be wrapped in VclPtr.",
@@ -142,6 +148,24 @@ bool VCLWidgets::VisitVarDecl( const VarDecl* varDecl )
return true;
}
+bool VCLWidgets::VisitFunctionDecl( const FunctionDecl* functionDecl )
+{
+ if (ignoreLocation(functionDecl)) {
+ return true;
+ }
+ QualType t1 { compat::getReturnType(*functionDecl) };
+ // check if this variables type is derived from Window
+ if (isPointerToWindowSubclass(t1)) {
+ report(
+ DiagnosticsEngine::Remark,
+ "vcl::Window subclass declared as a return type from a method/function, should be wrapped in VclPtr.",
+ functionDecl->getLocation())
+ << functionDecl->getSourceRange();
+ }
+ return true;
+}
+
+
loplugin::Plugin::Registration< VCLWidgets > X("vclwidgets");
}