summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/vclwidgets.cxx40
1 files changed, 40 insertions, 0 deletions
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx
index aa2af7fe5962..896cd3f38889 100644
--- a/compilerplugins/clang/vclwidgets.cxx
+++ b/compilerplugins/clang/vclwidgets.cxx
@@ -31,6 +31,8 @@ public:
virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
+ bool VisitCXXRecordDecl(const CXXRecordDecl * decl);
+
bool VisitFieldDecl(const FieldDecl * decl);
bool VisitParmVarDecl(ParmVarDecl const * decl);
@@ -76,6 +78,44 @@ bool isPointerToWindowSubclass(const QualType& pType) {
return isDerivedFromWindow(recordDecl);
}
+bool VCLWidgets::VisitCXXRecordDecl(const CXXRecordDecl * recordDecl) {
+ if (ignoreLocation(recordDecl)) {
+ return true;
+ }
+ if (!recordDecl->isCompleteDefinition())
+ return true;
+ // check if this field is derived from Window
+ if (!isDerivedFromWindow(recordDecl)) {
+ return true;
+ }
+ bool foundVclPtr = false;
+ for(auto fieldDecl : recordDecl->fields()) {
+ if (fieldDecl->getType().getAsString().find("VclPtr")==0) {
+ foundVclPtr = true;
+ break;
+ }
+ }
+ if (!foundVclPtr) {
+ return true;
+ }
+ bool foundDispose = false;
+ for(auto methodDecl : recordDecl->methods()) {
+ if (methodDecl->isInstance() && methodDecl->param_size()==0 && methodDecl->getNameAsString() == "dispose") {
+ foundDispose = true;
+ break;
+ }
+ }
+ if (!foundDispose) {
+ report(
+ DiagnosticsEngine::Warning,
+ "vcl::Window subclass with VclPtr members should declare a dispose() method.",
+ recordDecl->getLocation())
+ << recordDecl->getSourceRange();
+ }
+ return true;
+}
+
+
bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
if (ignoreLocation(fieldDecl)) {
return true;