bump product version to 7.2.5.1
[LibreOffice.git] / compilerplugins / clang / stringconcatauto.cxx
blobc7460cfcc8cda37271c36236a47f88cdfaef1d2a
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 * Based on LLVM/Clang.
7 * This file is distributed under the University of Illinois Open Source
8 * License. See LICENSE.TXT for details.
13 This is a compile check.
15 Warns about 'auto' declarations becoming rtl::OUStringConcat, such as
16 auto str = "string" + OUString::number( 10 );
17 The type of the expression is rtl::OUStringConcat and those refer to temporaries
18 and so their lifecycle should not extend the lifecycle of those temporaries.
21 #ifndef LO_CLANG_SHARED_PLUGINS
23 #include "plugin.hxx"
24 #include "check.hxx"
26 namespace loplugin
29 class StringConcatAuto
30 : public FilteringPlugin< StringConcatAuto >
32 public:
33 StringConcatAuto( const InstantiationData& data );
34 virtual void run() override;
35 bool shouldVisitTemplateInstantiations () const { return true; }
36 bool VisitVarDecl( const VarDecl* decl );
37 bool VisitFunctionDecl( const FunctionDecl* decl );
38 private:
39 enum class Check { Var, Return };
40 bool checkDecl( const DeclaratorDecl* decl, const QualType type, const SourceRange& range, Check check );
43 StringConcatAuto::StringConcatAuto( const InstantiationData& data )
44 : FilteringPlugin( data )
48 void StringConcatAuto::run()
50 TraverseDecl( compiler.getASTContext().getTranslationUnitDecl());
53 bool StringConcatAuto::VisitVarDecl( const VarDecl* decl )
55 return checkDecl( decl, decl->getType(),
56 decl->getTypeSourceInfo()
57 ? decl->getTypeSourceInfo()->getTypeLoc().getSourceRange()
58 : decl->getSourceRange(),
59 Check::Var );
62 bool StringConcatAuto::VisitFunctionDecl( const FunctionDecl* decl )
64 return checkDecl( decl, decl->getReturnType(), decl->getReturnTypeSourceRange(), Check::Return );
67 bool StringConcatAuto::checkDecl( const DeclaratorDecl* decl, QualType type, const SourceRange& range, Check check )
69 if( ignoreLocation( decl ))
70 return true;
71 if( isa< ParmVarDecl >( decl )) // parameters should be fine, temporaries should exist during the call
72 return true;
73 std::string fileName = getFilenameOfLocation(
74 compiler.getSourceManager().getSpellingLoc(compat::getBeginLoc(decl))).str();
75 loplugin::normalizeDotDotInFilePath(fileName);
76 if (loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/string.hxx")
77 || loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/ustring.hxx")
78 || loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/strbuf.hxx")
79 || loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/ustrbuf.hxx")
80 || loplugin::isSamePathname(fileName, SRCDIR "/include/rtl/stringconcat.hxx"))
81 return true;
82 auto const tc = loplugin::TypeCheck( type.getNonReferenceType().getCanonicalType());
83 const char* typeString = nullptr;
84 if( tc.Struct("OUStringConcat").Namespace("rtl").GlobalNamespace())
85 typeString = "OUString";
86 else if( tc.Struct("OStringConcat").Namespace("rtl").GlobalNamespace())
87 typeString = "OString";
88 else if( tc.Struct("OUStringNumber").Namespace("rtl").GlobalNamespace())
89 typeString = "OUString";
90 else if( tc.Struct("OStringNumber").Namespace("rtl").GlobalNamespace())
91 typeString = "OString";
92 else
93 return true;
94 report( DiagnosticsEngine::Warning,
95 check == Check::Var
96 ? "creating a variable of type %0 will make it reference temporaries"
97 : "returning a variable of type %0 will make it reference temporaries",
98 decl->getLocation())
99 << type;
100 report( DiagnosticsEngine::Note,
101 "use %0 instead",
102 range.getBegin())
103 << typeString
104 << FixItHint::CreateReplacement( range, typeString );
105 return true;
108 static Plugin::Registration< StringConcatAuto > stringconcatauto( "stringconcatauto" );
110 } // namespace
112 #endif // LO_CLANG_SHARED_PLUGINS
114 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */