compilerplugins/clang/badstatics.cxx |    4 -
 compilerplugins/clang/typecheck.hxx  |  129 +++++++++++++++++++++++++++++++++++
 2 files changed, 132 insertions(+), 1 deletion(-)

New commits:
commit 6e6c0951870c9b1149755aa21be2ec5d7145f347
Author: Stephan Bergmann <sberg...@redhat.com>
Date:   Tue Nov 17 21:50:45 2015 +0100

    Fix check for std::weak_ptr (that may be in an inline namespace)
    
    Change-Id: I048aef08df43d07544aafc69b711d258dc40bc21

diff --git a/compilerplugins/clang/badstatics.cxx 
b/compilerplugins/clang/badstatics.cxx
index 942b331..3b2881f 100644
--- a/compilerplugins/clang/badstatics.cxx
+++ b/compilerplugins/clang/badstatics.cxx
@@ -8,6 +8,7 @@
  */
 
 #include "plugin.hxx"
+#include "typecheck.hxx"
 
 namespace {
 
@@ -64,7 +65,8 @@ public:
             return std::make_pair(false, std::vector<FieldDecl const*>());
         }
         if (   startsWith(type, "class vcl::DeleteOnDeinit")
-            || startsWith(type, "class std::weak_ptr") // not owning
+            || loplugin::TypeCheck(rpType).Class("weak_ptr").StdNamespace()
+                // not owning
             || type == "class ImplWallpaper" // very odd static instance here
             || type == "class Application" // numerous odd subclasses in 
vclmain::createApplication()
             || type == "class DemoMtfApp" // one of these Application with own 
VclPtr
diff --git a/compilerplugins/clang/typecheck.hxx 
b/compilerplugins/clang/typecheck.hxx
new file mode 100644
index 0000000..6ab8f74
--- /dev/null
+++ b/compilerplugins/clang/typecheck.hxx
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_COMPILERPLUGINS_CLANG_TYPECHECK_HXX
+#define INCLUDED_COMPILERPLUGINS_CLANG_TYPECHECK_HXX
+
+#include <cstddef>
+
+#include <iostream>
+
+#include <clang/AST/DeclBase.h>
+#include <clang/AST/Type.h>
+
+namespace loplugin {
+
+class NamespaceCheck;
+
+class TypeCheck {
+public:
+    explicit TypeCheck(clang::QualType type): type_(type) {}
+
+    explicit operator bool() const { return !type_.isNull(); }
+
+    TypeCheck Const() const {
+        return
+            (!type_.isNull() && type_.isConstQualified()
+             && !type_.isVolatileQualified())
+            ? *this : TypeCheck();
+    }
+
+    TypeCheck LvalueReference() const {
+        if (!type_.isNull()) {
+            auto const t = type_->getAs<LValueReferenceType>();
+            if (t != nullptr) {
+                return TypeCheck(t->getPointeeType());
+            }
+        }
+        return TypeCheck();
+    }
+
+    template<std::size_t N> inline NamespaceCheck Class(char const (& id)[N])
+        const;
+
+private:
+    TypeCheck() = default;
+
+    clang::QualType const type_;
+};
+
+class TerminalCheck {
+public:
+    explicit operator bool() const { return satisfied_; }
+
+private:
+    friend NamespaceCheck;
+
+    explicit TerminalCheck(bool satisfied): satisfied_(satisfied) {}
+
+    bool const satisfied_;
+};
+
+class NamespaceCheck {
+public:
+    explicit operator bool() const { return context_ != nullptr; }
+
+    TerminalCheck GlobalNamespace() const {
+        return TerminalCheck(
+            context_ != nullptr
+            && ((context_->isLookupContext()
+                 ? context_ : context_->getLookupParent())
+                ->isTranslationUnit()));
+    }
+
+    template<std::size_t N> NamespaceCheck Namespace(char const (& id)[N]) 
const
+    {
+        if (context_) {
+            auto n = llvm::dyn_cast<clang::NamespaceDecl>(context_);
+            if (n != nullptr) {
+                auto const i = n->getIdentifier();
+                if (i != nullptr && i->isStr(id)) {
+                    return NamespaceCheck(n->getParent());
+                }
+            }
+        }
+        return NamespaceCheck();
+    }
+
+    TerminalCheck StdNamespace() const {
+        return TerminalCheck(context_ != nullptr && 
context_->isStdNamespace());
+    }
+
+private:
+    friend class TypeCheck;
+
+    explicit NamespaceCheck(clang::DeclContext const * context = nullptr):
+        context_(context) {}
+
+    clang::DeclContext const * const context_;
+};
+
+template<std::size_t N> NamespaceCheck TypeCheck::Class(char const (& id)[N])
+    const
+{
+    if (!type_.isNull()) {
+        auto const t = type_->getAs<RecordType>();
+        if (t != nullptr) {
+            auto const d = t->getDecl();
+            if (d->isClass()) {
+                auto const i = d->getIdentifier();
+                if (i != nullptr && i->isStr(id)) {
+                    return NamespaceCheck(d->getDeclContext());
+                }
+            }
+        }
+    }
+    return NamespaceCheck();
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to