summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/plugin.cxx
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2019-08-27 11:06:41 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-08-27 18:42:13 +0200
commit9e0b3423f21c23a8ef2fe749ea7dd7c1194c2f9a (patch)
tree26f2674f88359c5e6c3e1d0f888c7b31836c36ee /compilerplugins/clang/plugin.cxx
parentbbd500e14fce92b27cfc09e7cffd346e36eb5fb0 (diff)
loplugin:referencecasting find more redundant static_cast
Change-Id: I3a51812bbd3fcdc6b11e47cb12962f0d4fa7a2ae Reviewed-on: https://gerrit.libreoffice.org/78191 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins/clang/plugin.cxx')
-rw-r--r--compilerplugins/clang/plugin.cxx50
1 files changed, 50 insertions, 0 deletions
diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx
index 7e8dfb664b15..bf48e8822a03 100644
--- a/compilerplugins/clang/plugin.cxx
+++ b/compilerplugins/clang/plugin.cxx
@@ -697,6 +697,56 @@ bool hasCLanguageLinkageType(FunctionDecl const * decl) {
return false;
}
+static const CXXRecordDecl* stripTypeSugar(QualType qt)
+{
+ const clang::Type* t = qt.getTypePtr();
+ while (auto elaboratedType = dyn_cast<ElaboratedType>(t))
+ t = elaboratedType->desugar().getTypePtr();
+ auto recordType = dyn_cast<RecordType>(t);
+ if (!recordType)
+ return nullptr;
+ return dyn_cast_or_null<CXXRecordDecl>(recordType->getDecl());
+}
+
+int derivedFromCount(const CXXRecordDecl* subclassRecordDecl, const CXXRecordDecl* baseclassRecordDecl)
+{
+ if (!subclassRecordDecl || !baseclassRecordDecl)
+ return 0;
+ int derivedCount = 0;
+ if (subclassRecordDecl == baseclassRecordDecl)
+ derivedCount++;
+ if (!subclassRecordDecl->hasDefinition())
+ return derivedCount;
+ for (auto it = subclassRecordDecl->bases_begin(); it != subclassRecordDecl->bases_end(); ++it)
+ {
+ derivedCount += derivedFromCount(stripTypeSugar(it->getType()), baseclassRecordDecl);
+ // short-circuit, we only care about 0,1,2
+ if (derivedCount > 1)
+ return derivedCount;
+ }
+ for (auto it = subclassRecordDecl->vbases_begin(); it != subclassRecordDecl->vbases_end(); ++it)
+ {
+ derivedCount += derivedFromCount(stripTypeSugar(it->getType()), baseclassRecordDecl);
+ // short-circuit, we only care about 0,1,2
+ if (derivedCount > 1)
+ return derivedCount;
+ }
+ return derivedCount;
+}
+
+int derivedFromCount(QualType subclassQt, QualType baseclassQt)
+{
+ auto baseclassRecordDecl = stripTypeSugar(baseclassQt);
+ if (!baseclassRecordDecl)
+ return 0;
+ auto subclassRecordDecl = stripTypeSugar(subclassQt);
+ if (!subclassRecordDecl)
+ return 0;
+
+ return derivedFromCount(subclassRecordDecl, baseclassRecordDecl);
+}
+
+
} // namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */