c.s.tools.ide.analysis.modernize/src/com/sun/tools/ide/analysis/modernize/tools-clang.patch
branchrelease82
changeset 18423 b9d9af239a0c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/c.s.tools.ide.analysis.modernize/src/com/sun/tools/ide/analysis/modernize/tools-clang.patch	Wed Jun 07 20:23:29 2017 +0300
     1.3 @@ -0,0 +1,461 @@
     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