bump product version to 6.3.0.0.beta1
[LibreOffice.git] / compilerplugins / clang / externandnotdefined.cxx
blob72b250d3d82eca98496ea5cf69b901515ec258d4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #ifndef LO_CLANG_SHARED_PLUGINS
12 #include <string>
14 #include "plugin.hxx"
16 // Having an extern prototype for a method in a module and not actually declaring that method is dodgy.
19 namespace {
21 class ExternAndNotDefined:
22 public loplugin::FilteringPlugin<ExternAndNotDefined>
24 public:
25 explicit ExternAndNotDefined(loplugin::InstantiationData const & data): FilteringPlugin(data) {}
27 virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
29 bool VisitFunctionDecl(const FunctionDecl * decl);
32 bool ExternAndNotDefined::VisitFunctionDecl(const FunctionDecl * functionDecl) {
33 if (ignoreLocation(functionDecl)) {
34 return true;
36 if (functionDecl->isDefined() || functionDecl->isPure()
37 || (functionDecl->getLinkageAndVisibility().getLinkage()
38 != ExternalLinkage)) {
39 return true;
41 //TODO, filtering out anything template for now:
42 if (functionDecl->isDependentContext()) {
43 return true;
45 CXXRecordDecl const * r = dyn_cast<CXXRecordDecl>(functionDecl->getDeclContext());
46 if (r != nullptr && r->getTemplateSpecializationKind() != TSK_Undeclared) {
47 return true;
49 // this is the bison/flex C API, it has to be defined this way
50 std::string functionName = functionDecl->getNameAsString();
51 if (functionName == "yyerror" || functionName == "yyparse" || functionName == "yylex") {
52 return true;
54 // see vcl/unx/gtk/app/gtksys.cxx, typename conflicts prevent using the right include
55 if (functionName == "gdk_x11_screen_get_screen_number") {
56 return true;
58 if (!compiler.getSourceManager().isInMainFile(functionDecl->getLocation()))
60 return true;
62 StringRef fileName { getFileNameOfSpellingLoc(functionDecl->getLocation()) };
63 // the filters use some kind of dynamic loading stunt
64 if (loplugin::hasPathnamePrefix(fileName, SRCDIR "/filter/qa/")) {
65 return true;
67 report(
68 DiagnosticsEngine::Warning,
69 "extern prototype in main file without definition",
70 functionDecl->getLocation())
71 << functionDecl->getSourceRange();
72 return true;
76 loplugin::Plugin::Registration< ExternAndNotDefined > externandnotdefined("externandnotdefined");
80 #endif // LO_CLANG_SHARED_PLUGINS
82 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */