ide.analysis.modernize/src/org/netbeans/modules/ide/analysis/modernize/tools-clang.patch
1.1 --- a/ide.analysis.modernize/src/org/netbeans/modules/ide/analysis/modernize/tools-clang.patch Wed Jun 07 18:50:35 2017 +0300
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