c.s.tools.ide.analysis.modernize/src/com/sun/tools/ide/analysis/modernize/tools-clang.patch
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