/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * 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
bool VisitTagDecl(TagDecl* decl)
{ if (isa<ClassTemplateSpecializationDecl>(decl))
{ returntrue;
} if (!decl->isThisDeclarationADefinition())
{ returntrue;
} if (isa<CXXRecordDecl>(decl->getDeclContext()))
{ returntrue;
} if (!compiler.getLangOpts().CPlusPlus)
{ returntrue;
} if (autoconst d = dyn_cast<CXXRecordDecl>(decl))
{ if (d->getDescribedClassTemplate() != nullptr)
{ returntrue;
} if (hasSalDllpublicExportAttr(d))
{ // If the class definition has explicit default visibility, then assume that it // needs to be present (e.g., a backwards-compatibility stub like in // cppuhelper/source/compat.cxx): returntrue;
} if (derivesFromTestFixture(d))
{ // The names of CppUnit tests (that can be specified with CPPUNIT_TEST_NAME) are // tied to the fully-qualified names of classes derived from CppUnit::TestFixture, // so avoid unnamed namespaces in those classes' names: returntrue;
}
} return handleDeclaration(decl);
}
bool VisitFunctionDecl(FunctionDecl* decl)
{ if (isa<CXXMethodDecl>(decl))
{ returntrue;
} if (decl->getTemplatedKind() != FunctionDecl::TK_NonTemplate)
{ returntrue;
} if (!decl->isThisDeclarationADefinition())
{ returntrue;
} if (decl->isMain() || decl->isMSVCRTEntryPoint())
{ returntrue;
} if (loplugin::hasCLanguageLinkageType(decl)
&& loplugin::DeclCheck(decl).Function("_DllMainCRTStartup").GlobalNamespace())
{ returntrue;
} // If the function definition is explicit marked SAL_DLLPUBLIC_EXPORT or similar, then // assume that it needs to be present (e.g., only called via dlopen, or a backwards- // compatibility stub like in sal/osl/all/compat.cxx): if (hasSalDllpublicExportAttr(decl))
{ returntrue;
} autoconst canon = decl->getCanonicalDecl(); if (loplugin::hasCLanguageLinkageType(canon)
&& (canon->hasAttr<ConstructorAttr>() || canon->hasAttr<DestructorAttr>()))
{ returntrue;
} if (compiler.getDiagnostics().getDiagnosticLevel(diag::warn_unused_function,
decl->getLocation())
< DiagnosticsEngine::Warning)
{ // Don't warn about e.g. // // G_DEFINE_TYPE (GLOAction, g_lo_action, G_TYPE_OBJECT); // // in vcl/unx/gtk/gloactiongroup.cxx (which expands to non-static g_lo_action_get_type // function definition), which is already wrapped in // // #pragma GCC diagnostic ignored "-Wunused-function" returntrue;
} if (isInjectedFunction(decl))
{ returntrue;
} return handleDeclaration(decl);
}
bool VisitVarDecl(VarDecl* decl)
{ if (decl->isStaticDataMember())
{ returntrue;
} if (isa<VarTemplateSpecializationDecl>(decl))
{ returntrue;
} if (!decl->isThisDeclarationADefinition())
{ returntrue;
} if (loplugin::DeclCheck(decl).Var("_pRawDllMain").GlobalNamespace())
{ returntrue;
} return handleDeclaration(decl);
}
bool VisitClassTemplateDecl(ClassTemplateDecl* decl)
{ if (!decl->isThisDeclarationADefinition())
{ returntrue;
} if (isa<CXXRecordDecl>(decl->getDeclContext()))
{ returntrue;
} return handleDeclaration(decl);
}
bool VisitFunctionTemplateDecl(FunctionTemplateDecl* decl)
{ if (!decl->isThisDeclarationADefinition())
{ returntrue;
} if (isa<CXXRecordDecl>(decl->getDeclContext()))
{ returntrue;
} if (isInjectedFunction(decl->getTemplatedDecl()))
{ returntrue;
} return handleDeclaration(decl);
}
bool handleDeclaration(NamedDecl* decl)
{ if (ignoreLocation(decl))
{ returntrue;
} if (decl->getLinkageInternal() < compat::Linkage::Module)
{ returntrue;
} // In some cases getLinkageInternal() arguably wrongly reports ExternalLinkage, see the // commit message of <https://github.com/llvm/llvm-project/commit/ // df963a38a9e27fc43b485dfdf52bc1b090087e06> "DR1113: anonymous namespaces formally give // their contents internal linkage": // // "We still deviate from the standard in one regard here: extern "C" declarations // in anonymous namespaces are still granted external linkage. Changing those does // not appear to have been an intentional consequence of the standard change in // DR1113." // // Do not warn about such "wrongly external" declarations here: if (decl->isInAnonymousNamespace())
{ returntrue;
} for (Decl const* d = decl; d != nullptr; d = d->getPreviousDecl())
{ if (!compiler.getSourceManager().isInMainFile(d->getLocation()))
{ returntrue;
}
} if (compiler.getSourceManager().isMacroBodyExpansion(decl->getLocation()))
{ if (Lexer::getImmediateMacroName(decl->getLocation(), compiler.getSourceManager(),
compiler.getLangOpts())
== "MDDS_MTV_DEFINE_ELEMENT_CALLBACKS")
{ // Even wrapping in an unnamed namespace or sneaking "static" into the macro // wouldn't help, as then some of the functions it defines would be flagged as // unused: returntrue;
}
} elseif (compiler.getSourceManager().isMacroArgExpansion(decl->getLocation()))
{ if (Lexer::getImmediateMacroName(decl->getLocation(), compiler.getSourceManager(),
compiler.getLangOpts())
== "DEFINE_GUID")
{ // Windows, guiddef.h: returntrue;
}
}
TypedefNameDecl const* typedefed = nullptr; if (autoconst d = dyn_cast<TagDecl>(decl))
{
typedefed = d->getTypedefNameForAnonDecl();
} bool canStatic; if (autoconst d = dyn_cast<CXXRecordDecl>(decl))
{
canStatic = d->isUnion() && d->isAnonymousStructOrUnion();
} else
{
canStatic = isa<FunctionDecl>(decl) || isa<VarDecl>(decl)
|| isa<FunctionTemplateDecl>(decl) || isa<VarTemplateDecl>(decl);
} // In general, moving functions into an unnamed namespace can: break ADL like in // // struct S1 { int f() { return 1; } }; // int f(S1 s) { return s.f(); } // namespace N { // struct S2: S1 { int f() { return 0; } }; // int f(S2 s) { return s.f(); } // [*] // } // int main() { return f(N::S2()); } // // changing from returning 0 to returning 1 when [*] is moved into an unnamed namespace; can // conflict with function declarations in the moved function like in // // int f(int) { return 0; } // namespace { int f(int) { return 1; } } // int g() { // [*] // int f(int); // return f(0); // } // int main() { return g(); } // // changing from returning 0 to returning 1 when [*] is moved into an unnamed namespace; and // can conflict with overload resolution in general like in // // int f(int) { return 0; } // namespace { int f(...) { return 1; } } // int g() { return f(0); } // [*] // int main() { return g(); } // // changing from returning 0 to returning 1 when [*] is moved into an unnamed namespace: autoconst canUnnamed = compiler.getLangOpts().CPlusPlus
&& !(isa<FunctionDecl>(decl) || isa<FunctionTemplateDecl>(decl));
assert(canStatic || canUnnamed);
report(
DiagnosticsEngine::Warning,
("externally available%select{| typedef'ed}0 entity %1 is not previously declared in an" " included file (if it is only used in this translation unit," " %select{|make it static}2%select{| or }3%select{|put it in an unnamed namespace}4;" " otherwise, provide a declaration of it in an included file)"),
decl->getLocation())
<< (typedefed != nullptr) << (typedefed == nullptr ? decl : typedefed) << canStatic
<< (canStatic && canUnnamed) << canUnnamed << decl->getSourceRange(); for (auto d = decl->redecls_begin(); d != decl->redecls_end(); ++d)
{ if (*d == decl)
{ continue;
}
report(DiagnosticsEngine::Note, "another declaration is here", d->getLocation())
<< d->getSourceRange();
} //TODO: Class template specializations can be in the enclosing namespace, so no need to // list them here (as they won't need to be put into the unnamed namespace too, unlike for // specializations of function and variable templates); and explicit function template // specializations cannot have storage-class specifiers, so as we only suggest to make // function templates static (but not to move them into an unnamed namespace), no need to // list function template specializations here, either: if (autoconst d = dyn_cast<VarTemplateDecl>(decl))
{
reportSpecializations(d->specializations());
} if (isa<TagDecl>(decl) || isa<ClassTemplateDecl>(decl))
{
reportAssociatingFunctions(decl);
} returntrue;
}
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.