1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* Based on LLVM/Clang.
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*/
#ifndef LO_CLANG_SHARED_PLUGINS
#include "compat.hxx"
#include "plugin.hxx"
#include "check.hxx"
#include <iostream>
#include "clang/AST/CXXInheritance.h"
/*
* This is a compile-time checker.
*
* Check that when we override SvXmlImportContext, and we override createFastChildContext,
* we have also overridden startFastElement, or the fast-parser stuff will not work
* correctly.
*/
namespace
{
class XmlImport : public loplugin::FilteringPlugin<XmlImport>
{
public:
explicit XmlImport(loplugin::InstantiationData const& data)
: FilteringPlugin(data)
{
}
bool preRun() override
{
// std::string fn(handler.getMainFileName());
// loplugin::normalizeDotDotInFilePath(fn);
return true;
}
void run() override
{
if (preRun())
{
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
}
bool VisitCXXMethodDecl(const CXXMethodDecl*);
};
static bool containsStartFastElementMethod(const CXXRecordDecl* cxxRecordDecl,
bool& rbFoundImportContext)
{
auto dc = loplugin::DeclCheck(cxxRecordDecl);
if (dc.Class("SvXMLImportContext"))
{
rbFoundImportContext = true;
return false;
}
if (dc.Class("XFastContextHandler"))
return false;
for (auto it = cxxRecordDecl->method_begin(); it != cxxRecordDecl->method_end(); ++it)
{
auto i = *it;
if (i->getIdentifier() && i->getName() == "startFastElement")
{
// i->dump();
return true;
}
}
return false;
}
bool XmlImport::VisitCXXMethodDecl(const CXXMethodDecl* methodDecl)
{
auto beginLoc = compat::getBeginLoc(methodDecl);
if (!beginLoc.isValid() || ignoreLocation(beginLoc))
return true;
auto cxxRecordDecl = methodDecl->getParent();
if (!cxxRecordDecl || !cxxRecordDecl->getIdentifier())
return true;
auto className = cxxRecordDecl->getName();
if (className == "OOXMLFactory") // writerfilter
return true;
if (className == "SvXMLLegacyToFastDocHandler" || className == "ImportDocumentHandler"
|| className == "ExportDocumentHandler") // reportdesign
return true;
if (className == "XMLEmbeddedObjectExportFilter" || className == "XMLBasicExportFilter"
|| className == "XMLTransformerBase" || className == "SvXMLMetaExport") // xmloff
return true;
if (!methodDecl->getIdentifier())
return true;
if (!(methodDecl->getName() == "createFastChildContext" || methodDecl->getName() == "characters"
|| methodDecl->getName() == "endFastElement"))
return true;
if (loplugin::DeclCheck(cxxRecordDecl).Class("SvXMLImportContext"))
return true;
bool foundImportContext = false;
if (containsStartFastElementMethod(cxxRecordDecl, foundImportContext))
return true;
bool foundStartFastElement = false;
CXXBasePaths aPaths;
cxxRecordDecl->lookupInBases(
[&](const CXXBaseSpecifier* Specifier, CXXBasePath & /*Path*/) -> bool {
if (!Specifier->getType().getTypePtr())
return false;
const CXXRecordDecl* baseCXXRecordDecl = Specifier->getType()->getAsCXXRecordDecl();
if (!baseCXXRecordDecl)
return false;
if (baseCXXRecordDecl->isInvalidDecl())
return false;
foundStartFastElement
|= containsStartFastElementMethod(baseCXXRecordDecl, foundImportContext);
return false;
},
aPaths);
if (foundStartFastElement || !foundImportContext)
return true;
report(DiagnosticsEngine::Warning, "must override startFastElement too",
compat::getBeginLoc(methodDecl))
<< methodDecl->getSourceRange();
return true;
}
loplugin::Plugin::Registration<XmlImport> xmlimport("xmlimport");
} // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|