compilerplugins/clang/compat.hxx | 10 +++ compilerplugins/clang/includeform.cxx | 94 ++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+)
New commits: commit acb3ed0615a1b4e31257fa1014e9e2f2188c602c Author: Stephan Bergmann <sberg...@redhat.com> Date: Mon Oct 23 23:15:53 2017 +0200 loplugin:includeform Consistently use the #include "..." form for exactly those cases where the included file is located next to the including file, see the mail thread starting at <https://lists.freedesktop.org/archives/libreoffice/2017-October/078601.html> "C[++]: Normalizing include syntax ("" vs <>)". (For UNO API include files, see 189abcf0db61c41a565bd355294bf6e712fc3e5a "loplugin:includeform: UNO API include files".) (Some of the commits done earlier with messages containing "Change done in preparation of loplugin:includeform" etc. were based on a somewhat different earlier version of this plugin and would not be necessary with the current form. But they are harmless and reverting them would probably cause more noise than benefit, so just leave them in.) Change-Id: I9fe9268ed84d31b5df71857a2e535972b11254ce Reviewed-on: https://gerrit.libreoffice.org/43730 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Stephan Bergmann <sberg...@redhat.com> diff --git a/compilerplugins/clang/compat.hxx b/compilerplugins/clang/compat.hxx index 990f0ac78c26..532ce462887b 100644 --- a/compilerplugins/clang/compat.hxx +++ b/compilerplugins/clang/compat.hxx @@ -10,6 +10,7 @@ #ifndef INCLUDED_COMPILERPLUGINS_CLANG_COMPAT_HXX #define INCLUDED_COMPILERPLUGINS_CLANG_COMPAT_HXX +#include <cstddef> #include <memory> #include <string> @@ -36,6 +37,15 @@ // Compatibility wrapper to abstract over (trivial) changes in the Clang API: namespace compat { +inline llvm::StringRef take_front(llvm::StringRef ref, std::size_t N = 1) { +#if CLANG_VERSION >= 40000 + return ref.take_front(N); +#else + auto const size = ref.size(); + return N >= size ? ref : ref.drop_back(size - N); +#endif +} + inline bool isLookupContext(clang::DeclContext const & ctxt) { #if CLANG_VERSION >= 30700 return ctxt.isLookupContext(); diff --git a/compilerplugins/clang/includeform.cxx b/compilerplugins/clang/includeform.cxx new file mode 100644 index 000000000000..b3ab195fbe09 --- /dev/null +++ b/compilerplugins/clang/includeform.cxx @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "compat.hxx" +#include "plugin.hxx" + +namespace { + +class IncludeForm final: public PPCallbacks, public loplugin::RewritePlugin { +public: + explicit IncludeForm(InstantiationData const & data): RewritePlugin(data) + { compat::addPPCallbacks(compiler.getPreprocessor(), this); } + +private: + void run() override {} + + void InclusionDirective( + SourceLocation HashLoc, Token const & IncludeTok, StringRef, + bool IsAngled, CharSourceRange FilenameRange, FileEntry const * File, + StringRef SearchPath, StringRef, clang::Module const *) override + { + if (ignoreLocation(HashLoc)) { + return; + } + if (File == nullptr) { // in case of "fatal error: '...' file not found" + return; + } + if (IncludeTok.getIdentifierInfo()->getPPKeywordID() != tok::pp_include) + { + return; + } + auto const uno = isInUnoIncludeFile(HashLoc) + && !compiler.getSourceManager().isInMainFile(HashLoc); + // exclude the various compat.cxx that are included in + // isInUnoIncludeFile + //TODO: 'uno' should be false if HashLoc is inside an + // '#ifdef LIBO_INTERNAL_ONLY' block + bool shouldUseAngles; + if (uno) { + shouldUseAngles + = (!(loplugin::hasPathnamePrefix(SearchPath, SRCDIR) + || loplugin::hasPathnamePrefix(SearchPath, BUILDDIR)) + || loplugin::hasPathnamePrefix( + SearchPath, WORKDIR "/UnpackedTarball")); + } else { + auto const file = StringRef( + compiler.getSourceManager().getPresumedLoc(HashLoc) + .getFilename()); + auto const dir = compat::take_front(file, file.rfind('/')); + shouldUseAngles = !loplugin::isSamePathname(SearchPath, dir); + } + if (shouldUseAngles == IsAngled) { + return; + } + if (rewriter != nullptr) { + auto last = FilenameRange.getEnd().getLocWithOffset(-1); + if ((compiler.getSourceManager().getCharacterData( + FilenameRange.getBegin())[0] + == (IsAngled ? '<' : '"')) + && (compiler.getSourceManager().getCharacterData(last)[0] + == (IsAngled ? '>' : '"')) + && replaceText( + FilenameRange.getBegin(), 1, shouldUseAngles ? "<" : "\"") + && replaceText(last, 1, shouldUseAngles ? ">" : "\"")) + { + //TODO: atomically only replace both or neither + return; + } + } + report( + DiagnosticsEngine::Warning, + ("%select{|in UNO API include file, }0replace" + " %select{\"...\"|<...>}1 include form with" + " %select{\"...\"|<...>}2 for inclusion of %select{%select{a" + " source file next to the current source file|a source file not" + " next to the current source file, or a header}2|%select{a source" + " file|a header}2}0, %3"), + FilenameRange.getBegin()) + << uno << IsAngled << shouldUseAngles << File->getName() + << FilenameRange; + } +}; + +static loplugin::Plugin::Registration<IncludeForm> reg("includeform", true); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits