diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2015-11-17 21:50:45 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2015-11-17 21:50:45 +0100 |
commit | 6e6c0951870c9b1149755aa21be2ec5d7145f347 (patch) | |
tree | 7094ccd90a849ab5e1673ad4b0149aa2828023e6 /compilerplugins/clang | |
parent | 27b45cc23c7b8ea8a62e1fc901279fb3f09ae274 (diff) |
Fix check for std::weak_ptr (that may be in an inline namespace)
Change-Id: I048aef08df43d07544aafc69b711d258dc40bc21
Diffstat (limited to 'compilerplugins/clang')
-rw-r--r-- | compilerplugins/clang/badstatics.cxx | 4 | ||||
-rw-r--r-- | compilerplugins/clang/typecheck.hxx | 129 |
2 files changed, 132 insertions, 1 deletions
diff --git a/compilerplugins/clang/badstatics.cxx b/compilerplugins/clang/badstatics.cxx index 942b331f1749..3b2881f388d5 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 000000000000..6ab8f74e1aad --- /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: */ |