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/.
10 #ifndef LO_CLANG_SHARED_PLUGINS
17 /** Look for static OUString and OUString[], they can be more efficiently declared as:
19 static const OUStringLiteral our_aLBEntryMap[] = {" ", ", "};
20 static const OUStringLiteral sName("name");
22 which is more efficient at startup time.
27 : public loplugin::FilteringPlugin
<StringStatic
>
31 explicit StringStatic(loplugin::InstantiationData
const& rData
):
32 FilteringPlugin(rData
) {}
35 bool preRun() override
;
36 void postRun() override
;
37 bool VisitVarDecl(VarDecl
const*);
38 bool VisitReturnStmt(ReturnStmt
const*);
40 std::set
<VarDecl
const *> potentialVars
;
41 std::set
<VarDecl
const *> excludeVars
;
44 void StringStatic::run()
47 if( TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl()))
51 bool StringStatic::preRun()
53 StringRef
fn(handler
.getMainFileName());
54 // passing around pointers to global OUString
55 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/filter/source/svg/"))
57 // has a mix of literals and refs to external OUStrings
58 if (loplugin::isSamePathname(fn
, SRCDIR
"/ucb/source/ucp/webdav-neon/ContentProperties.cxx"))
63 void StringStatic::postRun()
65 for (auto const & pVarDecl
: excludeVars
) {
66 potentialVars
.erase(pVarDecl
);
68 for (auto const & varDecl
: potentialVars
) {
69 report(DiagnosticsEngine::Warning
,
70 "rather declare this using OUStringLiteral or char[]",
71 varDecl
->getLocation())
72 << varDecl
->getSourceRange();
76 bool StringStatic::VisitVarDecl(VarDecl
const* varDecl
)
78 if (ignoreLocation(varDecl
)) {
81 QualType qt
= varDecl
->getType();
82 if (!varDecl
->hasGlobalStorage()
83 || !varDecl
->isThisDeclarationADefinition()
84 || !qt
.isConstQualified()) {
87 if (qt
->isArrayType()) {
88 qt
= qt
->getAsArrayTypeUnsafe()->getElementType();
90 if (!loplugin::TypeCheck(qt
).Class("OUString").Namespace("rtl").GlobalNamespace()) {
93 if (varDecl
->hasInit()) {
94 Expr
const * expr
= varDecl
->getInit();
96 if (ExprWithCleanups
const * exprWithCleanups
= dyn_cast
<ExprWithCleanups
>(expr
)) {
97 expr
= exprWithCleanups
->getSubExpr();
99 else if (CastExpr
const * castExpr
= dyn_cast
<CastExpr
>(expr
)) {
100 expr
= castExpr
->getSubExpr();
102 else if (MaterializeTemporaryExpr
const * materializeExpr
= dyn_cast
<MaterializeTemporaryExpr
>(expr
)) {
103 expr
= materializeExpr
->GetTemporaryExpr();
105 else if (CXXBindTemporaryExpr
const * bindExpr
= dyn_cast
<CXXBindTemporaryExpr
>(expr
)) {
106 expr
= bindExpr
->getSubExpr();
108 else if (CXXConstructExpr
const * constructExpr
= dyn_cast
<CXXConstructExpr
>(expr
)) {
109 if (constructExpr
->getNumArgs() != 1) {
112 expr
= constructExpr
->getArg(0);
113 } else if (isa
<CallExpr
>(expr
)) {
120 potentialVars
.insert(varDecl
);
125 bool StringStatic::VisitReturnStmt(ReturnStmt
const * returnStmt
)
127 if (ignoreLocation(returnStmt
)) {
130 if (!returnStmt
->getRetValue()) {
133 DeclRefExpr
const * declRef
= dyn_cast
<DeclRefExpr
>(returnStmt
->getRetValue());
137 VarDecl
const * varDecl
= dyn_cast
<VarDecl
>(declRef
->getDecl());
139 excludeVars
.insert(varDecl
);
144 loplugin::Plugin::Registration
<StringStatic
> stringstatic("stringstatic");
148 #endif // LO_CLANG_SHARED_PLUGINS
150 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */