Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / compilerplugins / clang / externandnotdefined.cxx
blob5fd59ca4b58cb715ce7aafd56cb3aea129400fd7
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 report(
63 DiagnosticsEngine::Warning,
64 "extern prototype in main file without definition",
65 functionDecl->getLocation())
66 << functionDecl->getSourceRange();
67 return true;
71 loplugin::Plugin::Registration< ExternAndNotDefined > externandnotdefined("externandnotdefined");
75 #endif // LO_CLANG_SHARED_PLUGINS
77 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */