bump product version to 6.3.0.0.beta1
[LibreOffice.git] / compilerplugins / clang / stringstatic.cxx
bloba923da405f25e3a34aaef3f84503a122f27aa8dd
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 <set>
14 #include "check.hxx"
15 #include "plugin.hxx"
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.
24 namespace {
26 class StringStatic
27 : public loplugin::FilteringPlugin<StringStatic>
30 public:
31 explicit StringStatic(loplugin::InstantiationData const& rData):
32 FilteringPlugin(rData) {}
34 void run() override;
35 bool preRun() override;
36 void postRun() override;
37 bool VisitVarDecl(VarDecl const*);
38 bool VisitReturnStmt(ReturnStmt const*);
39 private:
40 std::set<VarDecl const *> potentialVars;
41 std::set<VarDecl const *> excludeVars;
44 void StringStatic::run()
46 if( preRun())
47 if( TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()))
48 postRun();
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/"))
56 return false;
57 // has a mix of literals and refs to external OUStrings
58 if (loplugin::isSamePathname(fn, SRCDIR "/ucb/source/ucp/webdav-neon/ContentProperties.cxx"))
59 return false;
60 return true;
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)) {
79 return true;
81 QualType qt = varDecl->getType();
82 if (!varDecl->hasGlobalStorage()
83 || !varDecl->isThisDeclarationADefinition()
84 || !qt.isConstQualified()) {
85 return true;
87 if (qt->isArrayType()) {
88 qt = qt->getAsArrayTypeUnsafe()->getElementType();
90 if (!loplugin::TypeCheck(qt).Class("OUString").Namespace("rtl").GlobalNamespace()) {
91 return true;
93 if (varDecl->hasInit()) {
94 Expr const * expr = varDecl->getInit();
95 while (true) {
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) {
110 return true;
112 expr = constructExpr->getArg(0);
113 } else if (isa<CallExpr>(expr)) {
114 return true;
115 } else {
116 break;
120 potentialVars.insert(varDecl);
122 return true;
125 bool StringStatic::VisitReturnStmt(ReturnStmt const * returnStmt)
127 if (ignoreLocation(returnStmt)) {
128 return true;
130 if (!returnStmt->getRetValue()) {
131 return true;
133 DeclRefExpr const * declRef = dyn_cast<DeclRefExpr>(returnStmt->getRetValue());
134 if (!declRef) {
135 return true;
137 VarDecl const * varDecl = dyn_cast<VarDecl>(declRef->getDecl());
138 if (varDecl) {
139 excludeVars.insert(varDecl);
141 return true;
144 loplugin::Plugin::Registration<StringStatic> stringstatic("stringstatic");
146 } // namespace
148 #endif // LO_CLANG_SHARED_PLUGINS
150 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */