tdf#153972 Fix color filter when cells have no content
[LibreOffice.git] / compilerplugins / clang / includeform.cxx
blob9d6587506a850d07e5023db98c074b3d49ebe510
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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>
12 #include "config_clang.h"
14 #include "plugin.hxx"
16 // Enforces the "Rules for #include directives (C/C++)" described in README.md.
18 namespace {
20 class IncludeForm final: public PPCallbacks, public loplugin::RewritePlugin {
21 public:
22 explicit IncludeForm(loplugin::InstantiationData const & data):
23 RewritePlugin(data)
24 { compiler.getPreprocessor().addPPCallbacks(std::unique_ptr<PPCallbacks>(this)); }
26 private:
27 void run() override {}
29 void InclusionDirective(
30 SourceLocation HashLoc, Token const & IncludeTok, StringRef,
31 bool IsAngled, CharSourceRange FilenameRange, FileEntry const * File,
32 StringRef SearchPath, StringRef, clang::Module const *
33 #if CLANG_VERSION >= 70000
34 , SrcMgr::CharacteristicKind
35 #endif
36 ) override
38 if (ignoreLocation(HashLoc)) {
39 return;
41 if (File == nullptr) { // in case of "fatal error: '...' file not found"
42 return;
44 if (IncludeTok.getIdentifierInfo()->getPPKeywordID() != tok::pp_include)
46 return;
48 auto const uno = isInUnoIncludeFile(HashLoc)
49 && !compiler.getSourceManager().isInMainFile(HashLoc);
50 // exclude the various compat.cxx that are included in
51 // isInUnoIncludeFile
52 //TODO: 'uno' should be false if HashLoc is inside an
53 // '#ifdef LIBO_INTERNAL_ONLY' block
54 bool shouldUseAngles;
55 if (uno) {
56 shouldUseAngles
57 = (!(loplugin::hasPathnamePrefix(SearchPath, SRCDIR "/")
58 || loplugin::hasPathnamePrefix(SearchPath, BUILDDIR "/"))
59 || loplugin::hasPathnamePrefix(
60 SearchPath, WORKDIR "/UnpackedTarball/"));
61 } else {
62 auto dir1 = std::string(SearchPath);
63 loplugin::normalizeDotDotInFilePath(dir1);
64 auto const file = StringRef(
65 compiler.getSourceManager().getPresumedLoc(HashLoc)
66 .getFilename());
67 auto pos = file.rfind('/');
68 #if defined _WIN32
69 auto const pos2 = file.rfind('\\');
70 if (pos2 != StringRef::npos
71 && (pos == StringRef::npos || pos2 > pos))
73 pos = pos2;
75 #endif
76 auto dir2 = std::string(file.take_front(pos));
77 loplugin::normalizeDotDotInFilePath(dir2);
78 shouldUseAngles = !loplugin::isSamePathname(dir1, dir2);
80 if (shouldUseAngles == IsAngled) {
81 return;
83 if (rewriter != nullptr) {
84 auto last = FilenameRange.getEnd().getLocWithOffset(-1);
85 if ((compiler.getSourceManager().getCharacterData(
86 FilenameRange.getBegin())[0]
87 == (IsAngled ? '<' : '"'))
88 && (compiler.getSourceManager().getCharacterData(last)[0]
89 == (IsAngled ? '>' : '"'))
90 && replaceText(
91 FilenameRange.getBegin(), 1, shouldUseAngles ? "<" : "\"")
92 && replaceText(last, 1, shouldUseAngles ? ">" : "\""))
94 //TODO: atomically only replace both or neither
95 return;
98 report(
99 DiagnosticsEngine::Warning,
100 ("%select{|in UNO API include file, }0replace"
101 " %select{\"...\"|<...>}1 include form with"
102 " %select{\"...\"|<...>}2 for inclusion of %select{%select{a"
103 " source file next to the current source file|a source file not"
104 " next to the current source file, or a header}2|%select{a source"
105 " file|a header}2}0, %3"),
106 FilenameRange.getBegin())
107 << uno << IsAngled << shouldUseAngles << File->getName()
108 << FilenameRange;
112 static loplugin::Plugin::Registration<IncludeForm> reg("includeform", true);
116 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */