summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compilerplugins/clang/compat.hxx73
-rw-r--r--compilerplugins/clang/redundantcast.cxx77
-rw-r--r--compilerplugins/clang/stringcopy.cxx5
3 files changed, 79 insertions, 76 deletions
diff --git a/compilerplugins/clang/compat.hxx b/compilerplugins/clang/compat.hxx
index 28dbeec71e20..a493cdc7b209 100644
--- a/compilerplugins/clang/compat.hxx
+++ b/compilerplugins/clang/compat.hxx
@@ -17,6 +17,7 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticIDs.h"
@@ -244,6 +245,78 @@ inline bool isStdNamespace(clang::DeclContext const & context) {
#endif
}
+// Work around <http://reviews.llvm.org/D22128>:
+//
+// SfxErrorHandler::GetClassString (svtools/source/misc/ehdl.cxx):
+//
+// ErrorResource_Impl aEr(aId, (sal_uInt16)lClassId);
+// if(aEr)
+// {
+// rStr = static_cast<ResString>(aEr).GetString();
+// }
+//
+// expr->dump():
+// CXXStaticCastExpr 0x2b74e8e657b8 'class ResString' static_cast<class ResString> <ConstructorConversion>
+// `-CXXBindTemporaryExpr 0x2b74e8e65798 'class ResString' (CXXTemporary 0x2b74e8e65790)
+// `-CXXConstructExpr 0x2b74e8e65758 'class ResString' 'void (class ResString &&) noexcept(false)' elidable
+// `-MaterializeTemporaryExpr 0x2b74e8e65740 'class ResString' xvalue
+// `-CXXBindTemporaryExpr 0x2b74e8e65720 'class ResString' (CXXTemporary 0x2b74e8e65718)
+// `-ImplicitCastExpr 0x2b74e8e65700 'class ResString' <UserDefinedConversion>
+// `-CXXMemberCallExpr 0x2b74e8e656d8 'class ResString'
+// `-MemberExpr 0x2b74e8e656a0 '<bound member function type>' .operator ResString 0x2b74e8dc1f00
+// `-DeclRefExpr 0x2b74e8e65648 'struct ErrorResource_Impl' lvalue Var 0x2b74e8e653b0 'aEr' 'struct ErrorResource_Impl'
+// expr->getSubExprAsWritten()->dump():
+// MaterializeTemporaryExpr 0x2b74e8e65740 'class ResString' xvalue
+// `-CXXBindTemporaryExpr 0x2b74e8e65720 'class ResString' (CXXTemporary 0x2b74e8e65718)
+// `-ImplicitCastExpr 0x2b74e8e65700 'class ResString' <UserDefinedConversion>
+// `-CXXMemberCallExpr 0x2b74e8e656d8 'class ResString'
+// `-MemberExpr 0x2b74e8e656a0 '<bound member function type>' .operator ResString 0x2b74e8dc1f00
+// `-DeclRefExpr 0x2b74e8e65648 'struct ErrorResource_Impl' lvalue Var 0x2b74e8e653b0 'aEr' 'struct ErrorResource_Impl'
+//
+// Copies code from Clang's lib/AST/Expr.cpp:
+namespace detail {
+ inline clang::Expr *skipImplicitTemporary(clang::Expr *expr) {
+ // Skip through reference binding to temporary.
+ if (clang::MaterializeTemporaryExpr *Materialize
+ = clang::dyn_cast<clang::MaterializeTemporaryExpr>(expr))
+ expr = Materialize->GetTemporaryExpr();
+
+ // Skip any temporary bindings; they're implicit.
+ if (clang::CXXBindTemporaryExpr *Binder = clang::dyn_cast<clang::CXXBindTemporaryExpr>(expr))
+ expr = Binder->getSubExpr();
+
+ return expr;
+ }
+}
+inline clang::Expr *getSubExprAsWritten(clang::CastExpr *This) {
+ clang::Expr *SubExpr = nullptr;
+ clang::CastExpr *E = This;
+ do {
+ SubExpr = detail::skipImplicitTemporary(E->getSubExpr());
+
+ // Conversions by constructor and conversion functions have a
+ // subexpression describing the call; strip it off.
+ if (E->getCastKind() == clang::CK_ConstructorConversion)
+ SubExpr =
+ detail::skipImplicitTemporary(clang::cast<clang::CXXConstructExpr>(SubExpr)->getArg(0));
+ else if (E->getCastKind() == clang::CK_UserDefinedConversion) {
+ assert((clang::isa<clang::CXXMemberCallExpr>(SubExpr) ||
+ clang::isa<clang::BlockExpr>(SubExpr)) &&
+ "Unexpected SubExpr for CK_UserDefinedConversion.");
+ if (clang::isa<clang::CXXMemberCallExpr>(SubExpr))
+ SubExpr = clang::cast<clang::CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument();
+ }
+
+ // If the subexpression we're left with is an implicit cast, look
+ // through that, too.
+ } while ((E = clang::dyn_cast<clang::ImplicitCastExpr>(SubExpr)));
+
+ return SubExpr;
+}
+inline const clang::Expr *getSubExprAsWritten(const clang::CastExpr *This) {
+ return getSubExprAsWritten(const_cast<clang::CastExpr *>(This));
+}
+
}
#endif
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx
index b7fbfd3c9010..3c38dd3ef495 100644
--- a/compilerplugins/clang/redundantcast.cxx
+++ b/compilerplugins/clang/redundantcast.cxx
@@ -26,82 +26,11 @@
#include "clang/Sema/Sema.h"
#include "check.hxx"
+#include "compat.hxx"
#include "plugin.hxx"
namespace {
-// Work around <http://reviews.llvm.org/D22128>:
-//
-// SfxErrorHandler::GetClassString (svtools/source/misc/ehdl.cxx):
-//
-// ErrorResource_Impl aEr(aId, (sal_uInt16)lClassId);
-// if(aEr)
-// {
-// rStr = static_cast<ResString>(aEr).GetString();
-// }
-//
-// expr->dump():
-// CXXStaticCastExpr 0x2b74e8e657b8 'class ResString' static_cast<class ResString> <ConstructorConversion>
-// `-CXXBindTemporaryExpr 0x2b74e8e65798 'class ResString' (CXXTemporary 0x2b74e8e65790)
-// `-CXXConstructExpr 0x2b74e8e65758 'class ResString' 'void (class ResString &&) noexcept(false)' elidable
-// `-MaterializeTemporaryExpr 0x2b74e8e65740 'class ResString' xvalue
-// `-CXXBindTemporaryExpr 0x2b74e8e65720 'class ResString' (CXXTemporary 0x2b74e8e65718)
-// `-ImplicitCastExpr 0x2b74e8e65700 'class ResString' <UserDefinedConversion>
-// `-CXXMemberCallExpr 0x2b74e8e656d8 'class ResString'
-// `-MemberExpr 0x2b74e8e656a0 '<bound member function type>' .operator ResString 0x2b74e8dc1f00
-// `-DeclRefExpr 0x2b74e8e65648 'struct ErrorResource_Impl' lvalue Var 0x2b74e8e653b0 'aEr' 'struct ErrorResource_Impl'
-// expr->getSubExprAsWritten()->dump():
-// MaterializeTemporaryExpr 0x2b74e8e65740 'class ResString' xvalue
-// `-CXXBindTemporaryExpr 0x2b74e8e65720 'class ResString' (CXXTemporary 0x2b74e8e65718)
-// `-ImplicitCastExpr 0x2b74e8e65700 'class ResString' <UserDefinedConversion>
-// `-CXXMemberCallExpr 0x2b74e8e656d8 'class ResString'
-// `-MemberExpr 0x2b74e8e656a0 '<bound member function type>' .operator ResString 0x2b74e8dc1f00
-// `-DeclRefExpr 0x2b74e8e65648 'struct ErrorResource_Impl' lvalue Var 0x2b74e8e653b0 'aEr' 'struct ErrorResource_Impl'
-//
-// Copies code from Clang's lib/AST/Expr.cpp:
-namespace {
- Expr *skipImplicitTemporary(Expr *expr) {
- // Skip through reference binding to temporary.
- if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(expr))
- expr = Materialize->GetTemporaryExpr();
-
- // Skip any temporary bindings; they're implicit.
- if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(expr))
- expr = Binder->getSubExpr();
-
- return expr;
- }
-}
-Expr *getSubExprAsWritten(CastExpr *This) {
- Expr *SubExpr = nullptr;
- CastExpr *E = This;
- do {
- SubExpr = skipImplicitTemporary(E->getSubExpr());
-
- // Conversions by constructor and conversion functions have a
- // subexpression describing the call; strip it off.
- if (E->getCastKind() == CK_ConstructorConversion)
- SubExpr =
- skipImplicitTemporary(cast<CXXConstructExpr>(SubExpr)->getArg(0));
- else if (E->getCastKind() == CK_UserDefinedConversion) {
- assert((isa<CXXMemberCallExpr>(SubExpr) ||
- isa<BlockExpr>(SubExpr)) &&
- "Unexpected SubExpr for CK_UserDefinedConversion.");
- if (isa<CXXMemberCallExpr>(SubExpr))
- SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument();
- }
-
- // If the subexpression we're left with is an implicit cast, look
- // through that, too.
- } while ((E = dyn_cast<ImplicitCastExpr>(SubExpr)));
-
- return SubExpr;
-}
-const Expr *getSubExprAsWritten(const CastExpr *This) {
- return getSubExprAsWritten(const_cast<CastExpr *>(This));
-}
-
bool isVoidPointer(QualType type) {
return type->isPointerType()
&& type->getAs<clang::PointerType>()->getPointeeType()->isVoidType();
@@ -322,7 +251,7 @@ bool RedundantCast::VisitCStyleCastExpr(CStyleCastExpr const * expr) {
if (isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(expr->getLocStart()))) {
return true;
}
- auto t1 = getSubExprAsWritten(expr)->getType();
+ auto t1 = compat::getSubExprAsWritten(expr)->getType();
auto t2 = expr->getTypeAsWritten();
if (t1 != t2) {
return true;
@@ -386,7 +315,7 @@ bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) {
if (ignoreLocation(expr)) {
return true;
}
- auto t1 = getSubExprAsWritten(expr)->getType();
+ auto t1 = compat::getSubExprAsWritten(expr)->getType();
auto t2 = expr->getTypeAsWritten();
if (t1.getCanonicalType() != t2.getCanonicalType()) {
return true;
diff --git a/compilerplugins/clang/stringcopy.cxx b/compilerplugins/clang/stringcopy.cxx
index c572b965bb9a..b1d8e22216ec 100644
--- a/compilerplugins/clang/stringcopy.cxx
+++ b/compilerplugins/clang/stringcopy.cxx
@@ -8,6 +8,7 @@
*/
#include "check.hxx"
+#include "compat.hxx"
#include "plugin.hxx"
namespace {
@@ -23,7 +24,7 @@ public:
return true;
}
auto const t1 = expr->getTypeAsWritten();
- auto const t2 = expr->getSubExprAsWritten()->getType();
+ auto const t2 = compat::getSubExprAsWritten(expr)->getType();
if ((t1.getCanonicalType().getTypePtr()
!= t2.getCanonicalType().getTypePtr())
|| !(loplugin::TypeCheck(t1).Class("OUString").Namespace("rtl")
@@ -46,7 +47,7 @@ private:
}
};
-static loplugin::Plugin::Registration<Visitor> reg("stringcopy", false);
+static loplugin::Plugin::Registration<Visitor> reg("stringcopy");
}