bump product version to 5.0.4.1
[LibreOffice.git] / compilerplugins / clang / externandnotdefined.cxx
blob2deca8adadcf0eb72c40b5130bfa1d5bbcac3b3c
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 #include <string>
12 #include "plugin.hxx"
13 #include "compat.hxx"
15 // Having an extern prototype for a method in a module and not actually declaring that method is dodgy.
18 namespace {
20 class ExternAndNotDefined:
21 public RecursiveASTVisitor<ExternAndNotDefined>, public loplugin::Plugin
23 public:
24 explicit ExternAndNotDefined(InstantiationData const & data): Plugin(data) {}
26 virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
28 bool VisitFunctionDecl(const FunctionDecl * decl);
31 bool ExternAndNotDefined::VisitFunctionDecl(const FunctionDecl * functionDecl) {
32 if (ignoreLocation(functionDecl)) {
33 return true;
35 if (functionDecl->isDefined() || functionDecl->isPure()
36 || (compat::getLinkage(functionDecl->getLinkageAndVisibility())
37 != ExternalLinkage)) {
38 return true;
40 //TODO, filtering out anything template for now:
41 if (functionDecl->isDependentContext()) {
42 return true;
44 CXXRecordDecl const * r = dyn_cast<CXXRecordDecl>(functionDecl->getDeclContext());
45 if (r != nullptr && r->getTemplateSpecializationKind() != TSK_Undeclared) {
46 return true;
48 // this is the bison/flex C API, it has to be defined this way
49 string functionName = functionDecl->getNameAsString();
50 if (functionName == "yyerror" || functionName == "YYWarning" || functionName == "yyparse" || functionName == "yylex") {
51 return true;
53 // see vcl/unx/gtk/app/gtksys.cxx, typename conflicts prevent using the right include
54 if (functionName == "gdk_x11_screen_get_screen_number") {
55 return true;
57 if (!compat::isInMainFile( compiler.getSourceManager(), functionDecl->getLocation())) {
58 return true;
60 StringRef fileName { compiler.getSourceManager().getFilename(functionDecl->getLocation()) };
61 // the filters use some kind of dynamic loading stunt
62 if (fileName.startswith(SRCDIR "/filter/qa/")) {
63 return true;
65 report(
66 DiagnosticsEngine::Warning,
67 "extern prototype in main file without definition",
68 functionDecl->getLocation())
69 << functionDecl->getSourceRange();
70 return true;
74 loplugin::Plugin::Registration< ExternAndNotDefined > X("externandnotdefined");
78 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */