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/.
16 #include <sys/types.h>
24 This is intended to be run as the second stage of the "unnecessaryvirtuals" clang plugin.
30 public RecursiveASTVisitor
<RemoveVirtuals
>, public loplugin::RewritePlugin
33 explicit RemoveVirtuals(InstantiationData
const & data
);
36 virtual void run() override
{ TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl()); }
38 bool VisitCXXMethodDecl( const CXXMethodDecl
* var
);
40 // I use a brute-force approach - mmap the results file and do a linear search on it
41 // It works surprisingly well, because the file is small enough to fit into L2 cache on modern CPU's
47 static size_t getFilesize(const char* filename
)
54 RemoveVirtuals::RemoveVirtuals(InstantiationData
const & data
): RewritePlugin(data
)
56 static const char sInputFile
[] = "/home/noel/libo4/result.txt";
57 mmapFilesize
= getFilesize(sInputFile
);
59 mmapFD
= open(sInputFile
, O_RDONLY
, 0);
62 mmappedData
= static_cast<char*>(mmap(NULL
, mmapFilesize
, PROT_READ
, MAP_PRIVATE
| MAP_POPULATE
, mmapFD
, 0));
63 assert(mmappedData
!= NULL
);
66 RemoveVirtuals::~RemoveVirtuals()
69 int rc
= munmap(mmappedData
, mmapFilesize
);
74 static std::string
niceName(const CXXMethodDecl
* functionDecl
)
77 functionDecl
->getParent()->getQualifiedNameAsString() + "::"
78 + compat::getReturnType(*functionDecl
).getAsString() + "-"
79 + functionDecl
->getNameAsString() + "(";
80 for (const ParmVarDecl
*pParmVarDecl
: functionDecl
->params()) {
81 s
+= pParmVarDecl
->getType().getAsString();
85 if (functionDecl
->isConst()) {
91 bool RemoveVirtuals::VisitCXXMethodDecl( const CXXMethodDecl
* functionDecl
)
93 if (rewriter
== nullptr) {
96 if (ignoreLocation(functionDecl
)) {
99 // ignore stuff that forms part of the stable URE interface
100 if (isInUnoIncludeFile(compiler
.getSourceManager().getSpellingLoc(
101 functionDecl
->getCanonicalDecl()->getNameInfo().getLoc()))) {
105 // don't mess with templates
106 if (functionDecl
->getParent()->getDescribedClassTemplate() != nullptr) {
109 if (functionDecl
->getTemplatedKind() != FunctionDecl::TK_NonTemplate
) {
113 if (!functionDecl
->isVirtualAsWritten()) {
116 std::string aNiceName
= "\n" + niceName(functionDecl
) + "\n";
117 const char *aNiceNameStr
= aNiceName
.c_str();
118 char* found
= std::search(mmappedData
, mmappedData
+ mmapFilesize
, aNiceNameStr
, aNiceNameStr
+ strlen(aNiceNameStr
));
119 if(!(found
< mmappedData
+ mmapFilesize
)) {
122 if (functionDecl
->isPure()) {
123 removeText(functionDecl
->getSourceRange());
125 std::string aOrigText
= rewriter
->getRewrittenText(functionDecl
->getSourceRange());
126 size_t iVirtualTokenIndex
= aOrigText
.find_first_of("virtual ");
127 if (iVirtualTokenIndex
== std::string::npos
) {
130 replaceText(functionDecl
->getSourceRange(), aOrigText
.replace(iVirtualTokenIndex
, strlen("virtual "), ""));
137 loplugin::Plugin::Registration
< RemoveVirtuals
> X("removevirtuals", false);
141 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */