1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
12 // Find function declarations that redundantly re-specify a visibility attribute
13 // (via SAL_DLLPUBLIC_EXPORT etc.) that was already specified with a previous
14 // declaration of that function. But MSVC wants consistency of __declspec
15 // across friend declarations, so just ignore those for now.
19 bool hasExplicitVisibilityAttr(Decl
const * decl
) {
20 VisibilityAttr
const * attr
= decl
->getAttr
<VisibilityAttr
>();
21 return attr
!= nullptr && !attr
->isInherited();
24 bool isFriendDecl(Decl
const * decl
) {
25 return decl
->getFriendObjectKind() != Decl::FOK_None
;
29 public loplugin::FilteringPlugin
<ReVisibility
>
32 explicit ReVisibility(InstantiationData
const & data
): FilteringPlugin(data
) {}
35 { TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl()); }
37 bool VisitFunctionDecl(FunctionDecl
const * decl
);
40 bool ReVisibility::VisitFunctionDecl(FunctionDecl
const * decl
) {
41 if (!ignoreLocation(decl
) && hasExplicitVisibilityAttr(decl
)
42 && !isFriendDecl(decl
))
44 Decl
const * first
= nullptr;
45 for (Decl
const * p
= decl
;;) {
46 p
= p
->getPreviousDecl();
51 if (hasExplicitVisibilityAttr(p
) && !isFriendDecl(p
)) {
53 DiagnosticsEngine::Warning
,
54 "Redundant visibility re-declaration",
55 decl
->getAttr
<VisibilityAttr
>()->getLocation())
56 << decl
->getAttr
<VisibilityAttr
>()->getRange();
58 DiagnosticsEngine::Note
,
59 "Previous visibility declaration is here",
60 p
->getAttr
<VisibilityAttr
>()->getLocation())
61 << p
->getAttr
<VisibilityAttr
>()->getRange();
65 if (decl
->isThisDeclarationADefinition() && first
!= nullptr
66 && !(getFilenameOfLocation(
67 compiler
.getSourceManager().getSpellingLoc(
69 .startswith(SRCDIR
"/libreofficekit/")))
72 DiagnosticsEngine::Warning
,
73 "Visibility declaration on definition, not first declaration",
74 decl
->getAttr
<VisibilityAttr
>()->getLocation())
75 << decl
->getAttr
<VisibilityAttr
>()->getRange();
77 DiagnosticsEngine::Note
, "First declaration is here",
79 << first
->getSourceRange();
85 loplugin::Plugin::Registration
<ReVisibility
> X("revisibility");
89 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */