bump product version to 6.3.0.0.beta1
[LibreOffice.git] / compilerplugins / clang / convertlong.cxx
blob07ec9e38a7e9df28f1b3b963f3c8f1f993d911dc
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 #include <memory>
11 #include <cassert>
12 #include <string>
13 #include <iostream>
14 #include <fstream>
15 #include <set>
16 #include "plugin.hxx"
17 #include "check.hxx"
19 /**
20 plugin to help to when converting code from
22 sal_uIntPtr/sal_uLong/sal_Long/long/unsigned long
24 to something more precise.
26 namespace
28 class ConvertLong : public loplugin::FilteringPlugin<ConvertLong>
30 public:
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")
42 return;
43 // too much magic
44 if (fn == SRCDIR "/sal/rtl/alloc_arena.cxx")
45 return;
46 if (fn == SRCDIR "/sal/rtl/alloc_cache.cxx")
47 return;
48 // TODO not sure what is going on here
49 if (fn == SRCDIR "/tools/source/generic/bigint.cxx")
50 return;
51 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
54 bool VisitVarDecl(VarDecl const*);
55 bool TraverseFunctionDecl(FunctionDecl*);
57 private:
58 bool isInterestingType(QualType qt);
61 bool ConvertLong::TraverseFunctionDecl(FunctionDecl* functionDecl)
63 // ignore template stuff
64 if (functionDecl->getTemplatedKind() != FunctionDecl::TK_NonTemplate)
66 return true;
68 return RecursiveASTVisitor::TraverseFunctionDecl(functionDecl);
71 bool ConvertLong::VisitVarDecl(VarDecl const* varDecl)
73 if (ignoreLocation(varDecl))
74 return true;
75 StringRef fileName{ getFileNameOfSpellingLoc(varDecl->getLocation()) };
76 if (loplugin::isSamePathname(fileName, SRCDIR "/include/tools/bigint.hxx"))
77 return true;
78 if (loplugin::isSamePathname(fileName, SRCDIR "/include/tools/solar.h"))
79 return true;
80 if (!varDecl->hasInit())
81 return true;
82 if (isa<IntegerLiteral>(varDecl->getInit()->IgnoreParenImpCasts()))
83 return true;
84 // ignore int x = -1;
85 if (isa<UnaryOperator>(varDecl->getInit()->IgnoreParenImpCasts()))
86 return true;
87 auto lhsType = varDecl->getType();
88 auto rhsType = varDecl->getInit()->IgnoreParenImpCasts()->getType();
89 if (lhsType.getLocalUnqualifiedType() == rhsType)
90 return true;
91 if (!rhsType.getTypePtrOrNull())
92 return true;
93 if (isInterestingType(rhsType))
94 return true;
95 if (!isInterestingType(lhsType))
96 return true;
97 if (rhsType->isFloatingType()) // TODO
98 return true;
99 report(DiagnosticsEngine::Warning, "rather replace type of decl %0 with %1",
100 varDecl->getLocation())
101 << lhsType << rhsType << varDecl->getSourceRange();
102 //lhsType->dump();
103 //varDecl->dump();
104 return true;
107 bool ConvertLong::isInterestingType(QualType qt)
109 auto tc = loplugin::TypeCheck(qt);
110 if (tc.Typedef())
112 TypedefType const* typedefType = qt->getAs<TypedefType>();
113 auto name = typedefType->getDecl()->getName();
114 if (name == "sal_uLong")
115 return true;
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)
118 return false;
120 if (isa<AutoType>(qt.getTypePtr()))
121 return false;
122 auto unqual = qt.getUnqualifiedType();
123 if (unqual->isSpecificBuiltinType(BuiltinType::Kind::Long)
124 || unqual->isSpecificBuiltinType(BuiltinType::Kind::ULong))
126 return true;
128 if (!tc.Typedef())
129 return false;
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: */