ide.analysis.modernize/src/org/netbeans/modules/ide/analysis/modernize/tools-clang.patch
changeset 18428 47444533169e
parent 18427 1520ed2e78e3
parent 18417 853976f2c616
child 18429 517409415907
     1.1 --- a/ide.analysis.modernize/src/org/netbeans/modules/ide/analysis/modernize/tools-clang.patch	Sun Jun 25 18:17:37 2017 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,461 +0,0 @@
     1.4 -Index: include/clang/Tooling/Core/Diagnostics.h
     1.5 -===================================================================
     1.6 ---- include/clang/Tooling/Core/Diagnostics.h	(revision 278390)
     1.7 -+++ include/clang/Tooling/Core/Diagnostics.h	(working copy)
     1.8 -@@ -1,254 +1,54 @@
     1.9 --//===--- Replacement.h - Framework for clang refactoring tools --*- C++ -*-===//
    1.10 --//
    1.11 --//                     The LLVM Compiler Infrastructure
    1.12 --//
    1.13 --// This file is distributed under the University of Illinois Open Source
    1.14 --// License. See LICENSE.TXT for details.
    1.15 --//
    1.16 --//===----------------------------------------------------------------------===//
    1.17 --//
    1.18 --//  Classes supporting refactorings that span multiple translation units.
    1.19 --//  While single translation unit refactorings are supported via the Rewriter,
    1.20 --//  when refactoring multiple translation units changes must be stored in a
    1.21 --//  SourceManager independent form, duplicate changes need to be removed, and
    1.22 --//  all changes must be applied at once at the end of the refactoring so that
    1.23 --//  the code is always parseable.
    1.24 --//
    1.25 --//===----------------------------------------------------------------------===//
    1.26 --
    1.27 --#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
    1.28 --#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
    1.29 --
    1.30 --#include "clang/Basic/LangOptions.h"
    1.31 --#include "clang/Basic/SourceLocation.h"
    1.32 --#include "llvm/ADT/StringRef.h"
    1.33 --#include "llvm/Support/Error.h"
    1.34 --#include <map>
    1.35 --#include <set>
    1.36 -+#ifndef LLVM_CLANG_TOOLING_CORE_DIAGNOSTICS_H
    1.37 -+#define LLVM_CLANG_TOOLING_CORE_DIAGNOSTICS_H
    1.38 -+#include "clang/Basic/Diagnostic.h"
    1.39 -+#include "llvm/ADT/SmallVector.h"
    1.40 -+#include "Replacement.h"
    1.41 - #include <string>
    1.42 --#include <vector>
    1.43 --
    1.44 - namespace clang {
    1.45 -+    namespace tooling {
    1.46 - 
    1.47 --class Rewriter;
    1.48 -+        struct DiagnosticsMessage {
    1.49 -+            DiagnosticsMessage(StringRef Message = "");
    1.50 -+            DiagnosticsMessage(StringRef Message, const SourceManager &Sources,
    1.51 -+                    SourceLocation Loc);
    1.52 -+            std::string Message;
    1.53 -+            std::string FilePath;
    1.54 -+            unsigned FileOffset;
    1.55 -+        };
    1.56 - 
    1.57 --namespace tooling {
    1.58 -+        struct Diagnostics {
    1.59 - 
    1.60 --/// \brief A source range independent of the \c SourceManager.
    1.61 --class Range {
    1.62 --public:
    1.63 --  Range() : Offset(0), Length(0) {}
    1.64 --  Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {}
    1.65 -+            enum Level {
    1.66 -+                Warning = DiagnosticsEngine::Warning,
    1.67 -+                Error = DiagnosticsEngine::Error
    1.68 -+            };
    1.69 - 
    1.70 --  /// \brief Accessors.
    1.71 --  /// @{
    1.72 --  unsigned getOffset() const { return Offset; }
    1.73 --  unsigned getLength() const { return Length; }
    1.74 --  /// @}
    1.75 -+            Diagnostics();
    1.76 -+            Diagnostics(StringRef CheckName, Level DiagLevel, bool IsWarningAsError,
    1.77 -+                    StringRef BuildDirectory);
    1.78 -+            std::string CheckName;
    1.79 -+            DiagnosticsMessage Message;
    1.80 -+            tooling::Replacements Fix;
    1.81 -+            SmallVector<DiagnosticsMessage, 1> Notes;
    1.82 - 
    1.83 --  /// \name Range Predicates
    1.84 --  /// @{
    1.85 --  /// \brief Whether this range overlaps with \p RHS or not.
    1.86 --  bool overlapsWith(Range RHS) const {
    1.87 --    return Offset + Length > RHS.Offset && Offset < RHS.Offset + RHS.Length;
    1.88 --  }
    1.89 -+            // A build directory of the diagnostic source file.
    1.90 -+            //
    1.91 -+            // It's an absolute path which is `directory` field of the source file in
    1.92 -+            // compilation database. If users don't specify the compilation database
    1.93 -+            // directory, it is the current directory where clang-tidy runs.
    1.94 -+            //
    1.95 -+            // Note: it is empty in unittest.
    1.96 -+            std::string BuildDirectory;
    1.97 - 
    1.98 --  /// \brief Whether this range contains \p RHS or not.
    1.99 --  bool contains(Range RHS) const {
   1.100 --    return RHS.Offset >= Offset &&
   1.101 --           (RHS.Offset + RHS.Length) <= (Offset + Length);
   1.102 --  }
   1.103 -+            Level DiagLevel;
   1.104 -+            bool IsWarningAsError;
   1.105 -+        };
   1.106 - 
   1.107 --  /// \brief Whether this range equals to \p RHS or not.
   1.108 --  bool operator==(const Range &RHS) const {
   1.109 --    return Offset == RHS.getOffset() && Length == RHS.getLength();
   1.110 --  }
   1.111 --  /// @}
   1.112 --
   1.113 --private:
   1.114 --  unsigned Offset;
   1.115 --  unsigned Length;
   1.116 --};
   1.117 --
   1.118 --/// \brief A text replacement.
   1.119 --///
   1.120 --/// Represents a SourceManager independent replacement of a range of text in a
   1.121 --/// specific file.
   1.122 --class Replacement {
   1.123 --public:
   1.124 --  /// \brief Creates an invalid (not applicable) replacement.
   1.125 --  Replacement();
   1.126 --
   1.127 --  /// \brief Creates a replacement of the range [Offset, Offset+Length) in
   1.128 --  /// FilePath with ReplacementText.
   1.129 --  ///
   1.130 --  /// \param FilePath A source file accessible via a SourceManager.
   1.131 --  /// \param Offset The byte offset of the start of the range in the file.
   1.132 --  /// \param Length The length of the range in bytes.
   1.133 --  Replacement(StringRef FilePath, unsigned Offset, unsigned Length,
   1.134 --              StringRef ReplacementText);
   1.135 --
   1.136 --  /// \brief Creates a Replacement of the range [Start, Start+Length) with
   1.137 --  /// ReplacementText.
   1.138 --  Replacement(const SourceManager &Sources, SourceLocation Start,
   1.139 --              unsigned Length, StringRef ReplacementText);
   1.140 --
   1.141 --  /// \brief Creates a Replacement of the given range with ReplacementText.
   1.142 --  Replacement(const SourceManager &Sources, const CharSourceRange &Range,
   1.143 --              StringRef ReplacementText,
   1.144 --              const LangOptions &LangOpts = LangOptions());
   1.145 --
   1.146 --  /// \brief Creates a Replacement of the node with ReplacementText.
   1.147 --  template <typename Node>
   1.148 --  Replacement(const SourceManager &Sources, const Node &NodeToReplace,
   1.149 --              StringRef ReplacementText,
   1.150 --              const LangOptions &LangOpts = LangOptions());
   1.151 --
   1.152 --  /// \brief Returns whether this replacement can be applied to a file.
   1.153 --  ///
   1.154 --  /// Only replacements that are in a valid file can be applied.
   1.155 --  bool isApplicable() const;
   1.156 --
   1.157 --  /// \brief Accessors.
   1.158 --  /// @{
   1.159 --  StringRef getFilePath() const { return FilePath; }
   1.160 --  unsigned getOffset() const { return ReplacementRange.getOffset(); }
   1.161 --  unsigned getLength() const { return ReplacementRange.getLength(); }
   1.162 --  StringRef getReplacementText() const { return ReplacementText; }
   1.163 --  /// @}
   1.164 --
   1.165 --  /// \brief Applies the replacement on the Rewriter.
   1.166 --  bool apply(Rewriter &Rewrite) const;
   1.167 --
   1.168 --  /// \brief Returns a human readable string representation.
   1.169 --  std::string toString() const;
   1.170 --
   1.171 -- private:
   1.172 --   void setFromSourceLocation(const SourceManager &Sources,
   1.173 --                              SourceLocation Start, unsigned Length,
   1.174 --                              StringRef ReplacementText);
   1.175 --   void setFromSourceRange(const SourceManager &Sources,
   1.176 --                           const CharSourceRange &Range,
   1.177 --                           StringRef ReplacementText,
   1.178 --                           const LangOptions &LangOpts);
   1.179 --
   1.180 --  std::string FilePath;
   1.181 --  Range ReplacementRange;
   1.182 --  std::string ReplacementText;
   1.183 --};
   1.184 --
   1.185 --/// \brief Less-than operator between two Replacements.
   1.186 --bool operator<(const Replacement &LHS, const Replacement &RHS);
   1.187 --
   1.188 --/// \brief Equal-to operator between two Replacements.
   1.189 --bool operator==(const Replacement &LHS, const Replacement &RHS);
   1.190 --
   1.191 --/// \brief A set of Replacements.
   1.192 --/// FIXME: Change to a vector and deduplicate in the RefactoringTool.
   1.193 --typedef std::set<Replacement> Replacements;
   1.194 --
   1.195 --/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
   1.196 --///
   1.197 --/// Replacement applications happen independently of the success of
   1.198 --/// other applications.
   1.199 --///
   1.200 --/// \returns true if all replacements apply. false otherwise.
   1.201 --bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
   1.202 --
   1.203 --/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
   1.204 --///
   1.205 --/// Replacement applications happen independently of the success of
   1.206 --/// other applications.
   1.207 --///
   1.208 --/// \returns true if all replacements apply. false otherwise.
   1.209 --bool applyAllReplacements(const std::vector<Replacement> &Replaces,
   1.210 --                          Rewriter &Rewrite);
   1.211 --
   1.212 --/// \brief Applies all replacements in \p Replaces to \p Code.
   1.213 --///
   1.214 --/// This completely ignores the path stored in each replacement. If all
   1.215 --/// replacements are applied successfully, this returns the code with
   1.216 --/// replacements applied; otherwise, an llvm::Error carrying llvm::StringError
   1.217 --/// is returned (the Error message can be converted to string using
   1.218 --/// `llvm::toString()` and 'std::error_code` in the `Error` should be ignored).
   1.219 --llvm::Expected<std::string> applyAllReplacements(StringRef Code,
   1.220 --                                                 const Replacements &Replaces);
   1.221 --
   1.222 --/// \brief Calculates how a code \p Position is shifted when \p Replaces are
   1.223 --/// applied.
   1.224 --unsigned shiftedCodePosition(const Replacements& Replaces, unsigned Position);
   1.225 --
   1.226 --/// \brief Calculates how a code \p Position is shifted when \p Replaces are
   1.227 --/// applied.
   1.228 --///
   1.229 --/// \pre Replaces[i].getOffset() <= Replaces[i+1].getOffset().
   1.230 --unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces,
   1.231 --                             unsigned Position);
   1.232 --
   1.233 --/// \brief Removes duplicate Replacements and reports if Replacements conflict
   1.234 --/// with one another. All Replacements are assumed to be in the same file.
   1.235 --///
   1.236 --/// \post Replaces[i].getOffset() <= Replaces[i+1].getOffset().
   1.237 --///
   1.238 --/// This function sorts \p Replaces so that conflicts can be reported simply by
   1.239 --/// offset into \p Replaces and number of elements in the conflict.
   1.240 --void deduplicate(std::vector<Replacement> &Replaces,
   1.241 --                 std::vector<Range> &Conflicts);
   1.242 --
   1.243 --/// \brief Collection of Replacements generated from a single translation unit.
   1.244 --struct TranslationUnitReplacements {
   1.245 --  /// Name of the main source for the translation unit.
   1.246 --  std::string MainSourceFile;
   1.247 --
   1.248 --  /// A freeform chunk of text to describe the context of the replacements.
   1.249 --  /// Will be printed, for example, when detecting conflicts during replacement
   1.250 --  /// deduplication.
   1.251 --  std::string Context;
   1.252 --
   1.253 --  std::vector<Replacement> Replacements;
   1.254 --};
   1.255 --
   1.256 --/// \brief Calculates the ranges in a single file that are affected by the
   1.257 --/// Replacements. Overlapping ranges will be merged.
   1.258 --///
   1.259 --/// \pre Replacements must be for the same file.
   1.260 --///
   1.261 --/// \returns a non-overlapping and sorted ranges.
   1.262 --std::vector<Range> calculateChangedRanges(const Replacements &Replaces);
   1.263 --
   1.264 --/// \brief Calculates the new ranges after \p Replaces are applied. These
   1.265 --/// include both the original \p Ranges and the affected ranges of \p Replaces
   1.266 --/// in the new code.
   1.267 --///
   1.268 --/// \pre Replacements must be for the same file.
   1.269 --///
   1.270 --/// \return The new ranges after \p Replaces are applied. The new ranges will be
   1.271 --/// sorted and non-overlapping.
   1.272 --std::vector<Range>
   1.273 --calculateRangesAfterReplacements(const Replacements &Replaces,
   1.274 --                                 const std::vector<Range> &Ranges);
   1.275 --
   1.276 --/// \brief Groups a random set of replacements by file path. Replacements
   1.277 --/// related to the same file entry are put into the same vector.
   1.278 --std::map<std::string, Replacements>
   1.279 --groupReplacementsByFile(const Replacements &Replaces);
   1.280 --
   1.281 --/// \brief Merges two sets of replacements with the second set referring to the
   1.282 --/// code after applying the first set. Within both 'First' and 'Second',
   1.283 --/// replacements must not overlap.
   1.284 --Replacements mergeReplacements(const Replacements &First,
   1.285 --                               const Replacements &Second);
   1.286 --
   1.287 --template <typename Node>
   1.288 --Replacement::Replacement(const SourceManager &Sources,
   1.289 --                         const Node &NodeToReplace, StringRef ReplacementText,
   1.290 --                         const LangOptions &LangOpts) {
   1.291 --  const CharSourceRange Range =
   1.292 --      CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
   1.293 --  setFromSourceRange(Sources, Range, ReplacementText, LangOpts);
   1.294 -+        struct TranslationUnitDiagnostics {
   1.295 -+            std::string MainSourceFile;
   1.296 -+            std::string Context;
   1.297 -+            std::vector<Diagnostics> Diags;
   1.298 -+        };
   1.299 -+    }
   1.300 - }
   1.301 --
   1.302 --} // end namespace tooling
   1.303 --} // end namespace clang
   1.304 --
   1.305 --#endif // LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
   1.306 -+#endif
   1.307 -\ No newline at end of file
   1.308 -Index: lib/Tooling/Core/CMakeLists.txt
   1.309 -===================================================================
   1.310 ---- lib/Tooling/Core/CMakeLists.txt	(revision 278390)
   1.311 -+++ lib/Tooling/Core/CMakeLists.txt	(working copy)
   1.312 -@@ -3,6 +3,7 @@
   1.313 - add_clang_library(clangToolingCore
   1.314 -   Lookup.cpp
   1.315 -   Replacement.cpp
   1.316 -+  Diagnostics.cpp
   1.317 -   QualTypeNames.cpp
   1.318 - 
   1.319 -   LINK_LIBS
   1.320 -Index: lib/Tooling/Core/Diagnostics.cpp
   1.321 -===================================================================
   1.322 ---- lib/Tooling/Core/Diagnostics.cpp	(revision 278390)
   1.323 -+++ lib/Tooling/Core/Diagnostics.cpp	(working copy)
   1.324 -@@ -1,113 +1,30 @@
   1.325 --//===--- Lookup.cpp - Framework for clang refactoring tools ---------------===//
   1.326 --//
   1.327 --//                     The LLVM Compiler Infrastructure
   1.328 --//
   1.329 --// This file is distributed under the University of Illinois Open Source
   1.330 --// License. See LICENSE.TXT for details.
   1.331 --//
   1.332 --//===----------------------------------------------------------------------===//
   1.333 --//
   1.334 --//  This file defines helper methods for clang tools performing name lookup.
   1.335 --//
   1.336 --//===----------------------------------------------------------------------===//
   1.337 -+#include "clang/Tooling/Core/Diagnostics.h"
   1.338 -+#include "clang/Basic/SourceManager.h"
   1.339 -+namespace clang {
   1.340 -+    namespace tooling {
   1.341 - 
   1.342 --#include "clang/Tooling/Core/Lookup.h"
   1.343 --#include "clang/AST/Decl.h"
   1.344 --using namespace clang;
   1.345 --using namespace clang::tooling;
   1.346 -+        DiagnosticsMessage::DiagnosticsMessage(StringRef Message)
   1.347 -+        : Message(Message), FileOffset(0) {
   1.348 -+        }
   1.349 - 
   1.350 --static bool isInsideDifferentNamespaceWithSameName(const DeclContext *DeclA,
   1.351 --                                                   const DeclContext *DeclB) {
   1.352 --  while (true) {
   1.353 --    // Look past non-namespaces on DeclA.
   1.354 --    while (DeclA && !isa<NamespaceDecl>(DeclA))
   1.355 --      DeclA = DeclA->getParent();
   1.356 -+        DiagnosticsMessage::DiagnosticsMessage(StringRef Message,
   1.357 -+                const SourceManager &Sources,
   1.358 -+                SourceLocation Loc)
   1.359 -+        : Message(Message) {
   1.360 -+            assert(Loc.isValid() && Loc.isFileID());
   1.361 -+            FilePath = Sources.getFilename(Loc);
   1.362 -+            FileOffset = Sources.getFileOffset(Loc);
   1.363 -+        }
   1.364 - 
   1.365 --    // Look past non-namespaces on DeclB.
   1.366 --    while (DeclB && !isa<NamespaceDecl>(DeclB))
   1.367 --      DeclB = DeclB->getParent();
   1.368 -+        Diagnostics::Diagnostics() {
   1.369 -+        }
   1.370 - 
   1.371 --    // We hit the root, no namespace collision.
   1.372 --    if (!DeclA || !DeclB)
   1.373 --      return false;
   1.374 --
   1.375 --    // Literally the same namespace, not a collision.
   1.376 --    if (DeclA == DeclB)
   1.377 --      return false;
   1.378 --
   1.379 --    // Now check the names. If they match we have a different namespace with the
   1.380 --    // same name.
   1.381 --    if (cast<NamespaceDecl>(DeclA)->getDeclName() ==
   1.382 --        cast<NamespaceDecl>(DeclB)->getDeclName())
   1.383 --      return true;
   1.384 --
   1.385 --    DeclA = DeclA->getParent();
   1.386 --    DeclB = DeclB->getParent();
   1.387 --  }
   1.388 --}
   1.389 --
   1.390 --static StringRef getBestNamespaceSubstr(const DeclContext *DeclA,
   1.391 --                                        StringRef NewName,
   1.392 --                                        bool HadLeadingColonColon) {
   1.393 --  while (true) {
   1.394 --    while (DeclA && !isa<NamespaceDecl>(DeclA))
   1.395 --      DeclA = DeclA->getParent();
   1.396 --
   1.397 --    // Fully qualified it is! Leave :: in place if it's there already.
   1.398 --    if (!DeclA)
   1.399 --      return HadLeadingColonColon ? NewName : NewName.substr(2);
   1.400 --
   1.401 --    // Otherwise strip off redundant namespace qualifications from the new name.
   1.402 --    // We use the fully qualified name of the namespace and remove that part
   1.403 --    // from NewName if it has an identical prefix.
   1.404 --    std::string NS =
   1.405 --        "::" + cast<NamespaceDecl>(DeclA)->getQualifiedNameAsString() + "::";
   1.406 --    if (NewName.startswith(NS))
   1.407 --      return NewName.substr(NS.size());
   1.408 --
   1.409 --    // No match yet. Strip of a namespace from the end of the chain and try
   1.410 --    // again. This allows to get optimal qualifications even if the old and new
   1.411 --    // decl only share common namespaces at a higher level.
   1.412 --    DeclA = DeclA->getParent();
   1.413 --  }
   1.414 --}
   1.415 --
   1.416 --/// Check if the name specifier begins with a written "::".
   1.417 --static bool isFullyQualified(const NestedNameSpecifier *NNS) {
   1.418 --  while (NNS) {
   1.419 --    if (NNS->getKind() == NestedNameSpecifier::Global)
   1.420 --      return true;
   1.421 --    NNS = NNS->getPrefix();
   1.422 --  }
   1.423 --  return false;
   1.424 --}
   1.425 --
   1.426 --std::string tooling::replaceNestedName(const NestedNameSpecifier *Use,
   1.427 --                                       const DeclContext *UseContext,
   1.428 --                                       const NamedDecl *FromDecl,
   1.429 --                                       StringRef ReplacementString) {
   1.430 --  assert(ReplacementString.startswith("::") &&
   1.431 --         "Expected fully-qualified name!");
   1.432 --
   1.433 --  // We can do a raw name replacement when we are not inside the namespace for
   1.434 --  // the original function and it is not in the global namespace.  The
   1.435 --  // assumption is that outside the original namespace we must have a using
   1.436 --  // statement that makes this work out and that other parts of this refactor
   1.437 --  // will automatically fix using statements to point to the new function
   1.438 --  const bool class_name_only = !Use;
   1.439 --  const bool in_global_namespace =
   1.440 --      isa<TranslationUnitDecl>(FromDecl->getDeclContext());
   1.441 --  if (class_name_only && !in_global_namespace &&
   1.442 --      !isInsideDifferentNamespaceWithSameName(FromDecl->getDeclContext(),
   1.443 --                                              UseContext)) {
   1.444 --    auto Pos = ReplacementString.rfind("::");
   1.445 --    return Pos != StringRef::npos ? ReplacementString.substr(Pos + 2)
   1.446 --                                  : ReplacementString;
   1.447 --  }
   1.448 --  // We did not match this because of a using statement, so we will need to
   1.449 --  // figure out how good a namespace match we have with our destination type.
   1.450 --  // We work backwards (from most specific possible namespace to least
   1.451 --  // specific).
   1.452 --  return getBestNamespaceSubstr(UseContext, ReplacementString,
   1.453 --                                isFullyQualified(Use));
   1.454 --}
   1.455 -+        Diagnostics::Diagnostics(StringRef CheckName,
   1.456 -+                Diagnostics::Level DiagLevel,
   1.457 -+                bool IsWarningAsError,
   1.458 -+                StringRef BuildDirectory)
   1.459 -+        : CheckName(CheckName), BuildDirectory(BuildDirectory), DiagLevel(DiagLevel),
   1.460 -+        IsWarningAsError(IsWarningAsError) {
   1.461 -+        }
   1.462 -+    }
   1.463 -+}
   1.464 -\ No newline at end of file