office-gobmx/compilerplugins/clang/reservedid.cxx
Stephan Bergmann d2c5490210 -Werror,-Wdeprecated-declarations
> compilerplugins/clang/casttovoid.cxx:452:18: error: 'endswith' is deprecated: Use ends_with instead [-Werror,-Wdeprecated-declarations]
>                 .endswith(".h"));
>                  ^~~~~~~~
>                  ends_with
> ~/llvm/inst/include/llvm/ADT/StringRef.h:276:19: note: 'endswith' has been explicitly marked deprecated here
>     [[nodiscard]] LLVM_DEPRECATED(
>                   ^

etc. after
<5ac12951b4>
"[ADT] Deprecate StringRef::{starts,ends}with (#75491)" on Clang 18 trunk, where
<1b97645e56>
"[ADT] Introduce StringRef::{starts,ends}_width{,_insensitive}" had been added
towards Clang 16

Change-Id: Icb3e43b7d6be6f877815285913d846f766eddebf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160919
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2023-12-18 17:40:26 +01:00

329 lines
13 KiB
C++

/* -*- 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 LO_CLANG_SHARED_PLUGINS
#include <algorithm>
#include <cassert>
#include <limits>
#include <set>
#include <string>
#include "clang/AST/Attr.h"
#include "config_clang.h"
#include "compat.hxx"
#include "plugin.hxx"
namespace {
bool isJniFunction(NamedDecl const * decl) {
auto const fdecl = dyn_cast<FunctionDecl>(decl);
if (fdecl == nullptr
|| !(decl->getDeclContext()->getDeclKind() == Decl::LinkageSpec
&& decl->getDeclContext()->getParent()->isTranslationUnit())
|| !fdecl->isExternC())
{
return false;
}
auto const id = decl->getIdentifier();
return id != nullptr && compat::starts_with(id->getName(), "Java_");
}
class ReservedId:
public loplugin::FilteringPlugin<ReservedId>
{
public:
explicit ReservedId(loplugin::InstantiationData const & data): FilteringPlugin(data)
{}
void run() override;
void postRun() override;
bool VisitNamedDecl(NamedDecl const * decl);
private:
enum class Kind {
Ok, DoubleUnderscore, UnderscoreUppercase, UnderscoreLowercase };
Kind determineKind(llvm::StringRef const & id);
bool isInLokIncludeFile(SourceLocation spellingLocation) const;
bool isApi(NamedDecl const * decl);
};
void ReservedId::run() {
//TODO: Rules for C?
if (TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()))
postRun();
}
void ReservedId::postRun() {
if( compiler.hasPreprocessor())
{
auto & prep = compiler.getPreprocessor();
for (auto const & m: prep.macros(false)) {
auto id = m.first->getName();
if (determineKind(id) != Kind::Ok
&& id != "_ATL_APARTMENT_THREADED"
// extensions/source/activex/StdAfx2.h
&& id != "_ATL_STATIC_REGISTRY"
// extensions/source/activex/StdAfx2.h
&& id != "_CRT_RAND_S" // sal/osl/w32/random.cxx
&& id != "_GLIBCXX_CDTOR_CALLABI"
&& id != "_HAS_AUTO_PTR_ETC" // unotools/source/i18n/resmgr.cxx
&& id != "_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR" // unotools/source/i18n/resmgr.cxx
&& id != "_MAX_PATH" // Windows
&& id != "_POSIX_SOURCE"
&& id != "_USE_MATH_DEFINES" // include/sal/config.h, Windows
&& id != "_WIN32_DCOM" // embedserv/source/embed/esdll.cxx
&& id != "_WTL_NO_CSTRING"
// fpicker/source/win32/filepicker/platform_vista.h (TODO:
// needed?)
&& id != "__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"
&& id != "__Column_FWD_DEFINED__"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK
// adoctint.h
&& id != "__Group_FWD_DEFINED__"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK
// adoctint.h
&& id != "__Index_FWD_DEFINED__"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK
// adoctint.h
&& id != "__Key_FWD_DEFINED__"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK
// adoctint.h
&& id != "__ORCUS_STATIC_LIB"
&& id != "__Table_FWD_DEFINED__"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK
// adoctint.h
&& id != "__USE_GNU"
&& id != "__User_FWD_DEFINED__")
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK
// adoctint.h
{
auto d = prep.getLocalMacroDirectiveHistory(m.first);
for (;;) {
if (d->getKind() == MacroDirective::MD_Define) {
auto loc = d->getLocation();
if (loc.isValid() && !ignoreLocation(loc) && !suppressWarningAt(loc)) {
auto file = getFilenameOfLocation(loc);
if (!loplugin::isSameUnoIncludePathname(
file,
"cppuhelper/implbase_ex_post.hxx")
&& !loplugin::isSameUnoIncludePathname(
file,
"cppuhelper/implbase_ex_pre.hxx"))
{
report(
DiagnosticsEngine::Warning,
"reserved macro identifier", loc);
}
}
}
d = d->getPrevious();
if (d == nullptr) {
break;
}
}
}
}
}
}
bool ReservedId::VisitNamedDecl(NamedDecl const * decl) {
auto spelLoc = compiler.getSourceManager().getSpellingLoc(
decl->getLocation());
if (ignoreLocation(spelLoc)) {
return true;
}
auto filename = getFilenameOfLocation(spelLoc);
if (loplugin::hasPathnamePrefix(filename, SRCDIR "/bridges/source/cpp_uno/")
&& (compat::ends_with(filename, "abi.hxx") || compat::ends_with(filename, "share.hxx")))
{
return true;
}
auto const id = decl->getIdentifier();
if (id == nullptr) {
return true;
}
auto const s = id->getName();
switch (determineKind(s)) {
case Kind::Ok:
break;
case Kind::DoubleUnderscore:
/*TODO*/if(s=="BIFF__5"||s=="XML__COLON"||s=="XML__EMPTY"||s=="XML__UNKNOWN_")break;
if (!(isApi(decl) || isJniFunction(decl))
&& s != "__CERT_DecodeDERCertificate"
// xmlsecurity/source/xmlsec/nss/nssrenam.h
&& s != "__CERT_NewTempCertificate"
// xmlsecurity/source/xmlsec/nss/nssrenam.h
&& s != "__CTFont"
// vcl/source/window/cairo_cairo.cxx -> include/vcl/sysdata.hxx
&& s != "__CxxDetectRethrow"
// bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
&& s != "__ImageBase"
// bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx, MS linker magic
&& s != "__PK11_GetKeyData"
// xmlsecurity/source/xmlsec/nss/nssrenam.h
&& s != "__current_exception" // bridges/inc/except.hxx, Windows
&& s != "__data_start") // sal/osl/unx/system.cxx
{
report(
DiagnosticsEngine::Warning,
"identifier %select{beginning with|containing}0 a double"
" underscore is reserved",
decl->getLocation())
<< compiler.getLangOpts().CPlusPlus << decl->getSourceRange();
}
break;
case Kind::UnderscoreUppercase:
if (!isApi(decl)
&& s != "_ADOColumn"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK adoctint.h
&& s != "_ADOGroup"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK adoctint.h
&& s != "_ADOIndex"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK adoctint.h
&& s != "_ADOKey"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK adoctint.h
&& s != "_ADOTable"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK adoctint.h
&& s != "_ADOUser"
// connectivity/source/inc/ado/Awrapadox.hxx, MS SDK adoctint.h
&& s != "_CustomCellRenderer" // vcl/unx/gtk3/customcellrenderer.hxx
&& s != "_CustomCellRendererClass" // vcl/unx/gtk3/customcellrenderer.cxx
&& s != "_FcPattern" // vcl/inc/unx/fc_fontoptions.hxx
&& s != "_GdkDisplay"
// vcl/unx/gtk/xid_fullscreen_on_all_monitors.c
&& s != "_GdkEvent" // vcl/unx/gtk/xid_fullscreen_on_all_monitors.c
&& s != "_GdkScreen" // vcl/unx/gtk/xid_fullscreen_on_all_monitors.c
&& s != "_GdkWindow"
// vcl/unx/gtk/xid_fullscreen_on_all_monitors.c
&& s != "_GstVideoOverlay"
// avmedia/source/gstreamer/gstplayer.hxx
&& s != "_GtkMediaStream"
// avmedia/source/gtk/gtkplayer.hxx
&& s != "_GtkWidget"
// avmedia/source/gtk/gtkplayer.hxx
&& s != "_Module" // extensions/source/activex/StdAfx2.h, CComModule
&& s != "_NotifyingLayout" // vcl/unx/gtk4/notifyinglayout.cxx
&& s != "_SurfacePaintable" // vcl/unx/gtk3/gtkinst.cxx
&& s != "_SurfacePaintableClass" // vcl/unx/gtk3/gtkinst.cxx
&& s != "_SurfaceCellRenderer" // vcl/unx/gtk4/surfacecellrenderer.cxx
&& s != "_SurfaceCellRendererClass" // vcl/unx/gtk4/surfacecellrenderer.cxx
&& s != "_TransferableContent" // vcl/unx/gtk4/transferableprovider.cxx
&& s != "_TransferableContentClass") // vcl/unx/gtk4/transferableprovider.cxx
{
report(
DiagnosticsEngine::Warning,
"identifier beginning with an underscore followed by an"
" uppercase letter is reserved",
decl->getLocation())
<< decl->getSourceRange();
}
break;
case Kind::UnderscoreLowercase:
if (decl->getDeclContext()->isTranslationUnit()
&& !isa<ParmVarDecl>(decl) && !isApi(decl)
&& s != "_cairo" && s != "_cairo_surface"
// tools/source/ref/errinf.cxx -> include/vcl/window.hxx ->
// include/vcl/outdev.hxx -> include/vcl/cairo.hxx
&& s != "_cairo_font_options"
// vcl/source/window/accessibility.cxx -> vcl/inc/salinst.hxx
&& s != "_cairo_user_data_key"
// vcl/headless/svpbmp.cxx -> vcl/inc/headless/svpgdi.hxx
&& s != "_end" // sal/osl/unx/system.cxx
&& s != "_rtl_Locale"
// i18nlangtag/source/isolang/mslangid.cxx ->
// include/i18nlangtag/languagetag.hxx
&& s != "_uno_ExtEnvironment"
// cppu/source/threadpool/threadident.cxx ->
// threadpool/current.hxx
&& s != "_xmlTextWriter") // include/svl/poolitem.hxx
{
report(
DiagnosticsEngine::Warning,
"identifier beginning with an underscore followed by a"
" lowercase letter is reserved in the global namespace",
decl->getLocation())
<< decl->getSourceRange();
}
break;
}
return true;
}
ReservedId::Kind ReservedId::determineKind(llvm::StringRef const & id) {
if (compiler.getLangOpts().CPlusPlus
&& id.find("__") != llvm::StringRef::npos)
{
return Kind::DoubleUnderscore;
}
if (id.size() >= 2 && id[0] == '_') {
auto c = id[1];
if (c == '_') {
return Kind::DoubleUnderscore;
}
if (c >= 'A' && c <= 'Z') {
return Kind::UnderscoreUppercase;
}
if (c >= 'a' && c <= 'z') {
return Kind::UnderscoreLowercase;
}
}
return Kind::Ok;
}
bool ReservedId::isInLokIncludeFile(SourceLocation spellingLocation) const {
return loplugin::hasPathnamePrefix(
getFilenameOfLocation(spellingLocation),
SRCDIR "/include/LibreOfficeKit/");
}
bool ReservedId::isApi(NamedDecl const * decl) {
auto const fdecl = dyn_cast<FunctionDecl>(decl);
if (fdecl != nullptr) {
decl = fdecl->getCanonicalDecl();
} else {
auto const tdecl = dyn_cast<TagDecl>(decl);
if (tdecl != nullptr) {
decl = tdecl->getCanonicalDecl();
}
}
auto const loc = compiler.getSourceManager().getSpellingLoc(
decl->getLocation());
if (!(isInUnoIncludeFile(loc) || isInLokIncludeFile(loc))
|| isa<ParmVarDecl>(decl))
{
return false;
}
auto const ctx = decl->getDeclContext();
if (ctx->isTranslationUnit()
|| (ctx->getDeclKind() == Decl::LinkageSpec
&& ctx->getParent()->isTranslationUnit()))
{
return true;
}
if (ctx->isNamespace()) {
auto const id = dyn_cast<NamespaceDecl>(ctx)->getIdentifier();
return !(id == nullptr || id->getName() == "detail");
}
return false;
}
loplugin::Plugin::Registration<ReservedId> reservedid("reservedid");
}
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */