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/.
20 plugin to help to when converting code from
22 sal_uIntPtr/sal_uLong/sal_Long/long/unsigned long
24 to something more precise.
28 class ConvertLong
: public loplugin::FilteringPlugin
<ConvertLong
>
31 explicit ConvertLong(loplugin::InstantiationData
const& data
)
32 : FilteringPlugin(data
)
36 virtual void run() override
38 std::string
fn(handler
.getMainFileName());
39 loplugin::normalizeDotDotInFilePath(fn
);
40 // using sal_uIntPtr as in-between type when converting void* to rtl_TextEncoding
41 if (fn
== SRCDIR
"/sal/osl/unx/thread.cxx")
44 if (fn
== SRCDIR
"/sal/rtl/alloc_arena.cxx")
46 if (fn
== SRCDIR
"/sal/rtl/alloc_cache.cxx")
48 // TODO not sure what is going on here
49 if (fn
== SRCDIR
"/tools/source/generic/bigint.cxx")
51 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
54 bool VisitVarDecl(VarDecl
const*);
55 bool TraverseFunctionDecl(FunctionDecl
*);
58 bool isInterestingType(QualType qt
);
61 bool ConvertLong::TraverseFunctionDecl(FunctionDecl
* functionDecl
)
63 // ignore template stuff
64 if (functionDecl
->getTemplatedKind() != FunctionDecl::TK_NonTemplate
)
68 return RecursiveASTVisitor::TraverseFunctionDecl(functionDecl
);
71 bool ConvertLong::VisitVarDecl(VarDecl
const* varDecl
)
73 if (ignoreLocation(varDecl
))
75 StringRef fileName
{ getFileNameOfSpellingLoc(varDecl
->getLocation()) };
76 if (loplugin::isSamePathname(fileName
, SRCDIR
"/include/tools/bigint.hxx"))
78 if (loplugin::isSamePathname(fileName
, SRCDIR
"/include/tools/solar.h"))
80 if (!varDecl
->hasInit())
82 if (isa
<IntegerLiteral
>(varDecl
->getInit()->IgnoreParenImpCasts()))
85 if (isa
<UnaryOperator
>(varDecl
->getInit()->IgnoreParenImpCasts()))
87 auto lhsType
= varDecl
->getType();
88 auto rhsType
= varDecl
->getInit()->IgnoreParenImpCasts()->getType();
89 if (lhsType
.getLocalUnqualifiedType() == rhsType
)
91 if (!rhsType
.getTypePtrOrNull())
93 if (isInterestingType(rhsType
))
95 if (!isInterestingType(lhsType
))
97 if (rhsType
->isFloatingType()) // TODO
99 report(DiagnosticsEngine::Warning
, "rather replace type of decl %0 with %1",
100 varDecl
->getLocation())
101 << lhsType
<< rhsType
<< varDecl
->getSourceRange();
107 bool ConvertLong::isInterestingType(QualType qt
)
109 auto tc
= loplugin::TypeCheck(qt
);
112 TypedefType
const* typedefType
= qt
->getAs
<TypedefType
>();
113 auto name
= typedefType
->getDecl()->getName();
114 if (name
== "sal_uLong")
116 // because this is a typedef to long on 64-bit Linux
117 if (name
== "sal_Int64" || name
== "sal_uInt64" || name
.find("size_t") != StringRef::npos
)
120 if (isa
<AutoType
>(qt
.getTypePtr()))
122 auto unqual
= qt
.getUnqualifiedType();
123 if (unqual
->isSpecificBuiltinType(BuiltinType::Kind::Long
)
124 || unqual
->isSpecificBuiltinType(BuiltinType::Kind::ULong
))
130 TypedefType
const* typedefType
= qt
->getAs
<TypedefType
>();
131 auto name
= typedefType
->getDecl()->getName();
132 return name
== "sal_uIntPtr" || name
== "sal_IntPtr";
135 loplugin::Plugin::Registration
<ConvertLong
> X("convertlong", false);
138 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */