c.s.tools.ide.analysis.modernize/src/com/sun/tools/ide/analysis/modernize/tools-clang.patch
1 Index: include/clang/Tooling/Core/Diagnostics.h
2 ===================================================================
3 --- include/clang/Tooling/Core/Diagnostics.h (revision 278390)
4 +++ include/clang/Tooling/Core/Diagnostics.h (working copy)
6 -//===--- Replacement.h - Framework for clang refactoring tools --*- C++ -*-===//
8 -// The LLVM Compiler Infrastructure
10 -// This file is distributed under the University of Illinois Open Source
11 -// License. See LICENSE.TXT for details.
13 -//===----------------------------------------------------------------------===//
15 -// Classes supporting refactorings that span multiple translation units.
16 -// While single translation unit refactorings are supported via the Rewriter,
17 -// when refactoring multiple translation units changes must be stored in a
18 -// SourceManager independent form, duplicate changes need to be removed, and
19 -// all changes must be applied at once at the end of the refactoring so that
20 -// the code is always parseable.
22 -//===----------------------------------------------------------------------===//
24 -#ifndef LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
25 -#define LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
27 -#include "clang/Basic/LangOptions.h"
28 -#include "clang/Basic/SourceLocation.h"
29 -#include "llvm/ADT/StringRef.h"
30 -#include "llvm/Support/Error.h"
33 +#ifndef LLVM_CLANG_TOOLING_CORE_DIAGNOSTICS_H
34 +#define LLVM_CLANG_TOOLING_CORE_DIAGNOSTICS_H
35 +#include "clang/Basic/Diagnostic.h"
36 +#include "llvm/ADT/SmallVector.h"
37 +#include "Replacement.h"
45 + struct DiagnosticsMessage {
46 + DiagnosticsMessage(StringRef Message = "");
47 + DiagnosticsMessage(StringRef Message, const SourceManager &Sources,
48 + SourceLocation Loc);
49 + std::string Message;
50 + std::string FilePath;
51 + unsigned FileOffset;
55 + struct Diagnostics {
57 -/// \brief A source range independent of the \c SourceManager.
60 - Range() : Offset(0), Length(0) {}
61 - Range(unsigned Offset, unsigned Length) : Offset(Offset), Length(Length) {}
63 + Warning = DiagnosticsEngine::Warning,
64 + Error = DiagnosticsEngine::Error
67 - /// \brief Accessors.
69 - unsigned getOffset() const { return Offset; }
70 - unsigned getLength() const { return Length; }
73 + Diagnostics(StringRef CheckName, Level DiagLevel, bool IsWarningAsError,
74 + StringRef BuildDirectory);
75 + std::string CheckName;
76 + DiagnosticsMessage Message;
77 + tooling::Replacements Fix;
78 + SmallVector<DiagnosticsMessage, 1> Notes;
80 - /// \name Range Predicates
82 - /// \brief Whether this range overlaps with \p RHS or not.
83 - bool overlapsWith(Range RHS) const {
84 - return Offset + Length > RHS.Offset && Offset < RHS.Offset + RHS.Length;
86 + // A build directory of the diagnostic source file.
88 + // It's an absolute path which is `directory` field of the source file in
89 + // compilation database. If users don't specify the compilation database
90 + // directory, it is the current directory where clang-tidy runs.
92 + // Note: it is empty in unittest.
93 + std::string BuildDirectory;
95 - /// \brief Whether this range contains \p RHS or not.
96 - bool contains(Range RHS) const {
97 - return RHS.Offset >= Offset &&
98 - (RHS.Offset + RHS.Length) <= (Offset + Length);
101 + bool IsWarningAsError;
104 - /// \brief Whether this range equals to \p RHS or not.
105 - bool operator==(const Range &RHS) const {
106 - return Offset == RHS.getOffset() && Length == RHS.getLength();
115 -/// \brief A text replacement.
117 -/// Represents a SourceManager independent replacement of a range of text in a
121 - /// \brief Creates an invalid (not applicable) replacement.
124 - /// \brief Creates a replacement of the range [Offset, Offset+Length) in
125 - /// FilePath with ReplacementText.
127 - /// \param FilePath A source file accessible via a SourceManager.
128 - /// \param Offset The byte offset of the start of the range in the file.
129 - /// \param Length The length of the range in bytes.
130 - Replacement(StringRef FilePath, unsigned Offset, unsigned Length,
131 - StringRef ReplacementText);
133 - /// \brief Creates a Replacement of the range [Start, Start+Length) with
134 - /// ReplacementText.
135 - Replacement(const SourceManager &Sources, SourceLocation Start,
136 - unsigned Length, StringRef ReplacementText);
138 - /// \brief Creates a Replacement of the given range with ReplacementText.
139 - Replacement(const SourceManager &Sources, const CharSourceRange &Range,
140 - StringRef ReplacementText,
141 - const LangOptions &LangOpts = LangOptions());
143 - /// \brief Creates a Replacement of the node with ReplacementText.
144 - template <typename Node>
145 - Replacement(const SourceManager &Sources, const Node &NodeToReplace,
146 - StringRef ReplacementText,
147 - const LangOptions &LangOpts = LangOptions());
149 - /// \brief Returns whether this replacement can be applied to a file.
151 - /// Only replacements that are in a valid file can be applied.
152 - bool isApplicable() const;
154 - /// \brief Accessors.
156 - StringRef getFilePath() const { return FilePath; }
157 - unsigned getOffset() const { return ReplacementRange.getOffset(); }
158 - unsigned getLength() const { return ReplacementRange.getLength(); }
159 - StringRef getReplacementText() const { return ReplacementText; }
162 - /// \brief Applies the replacement on the Rewriter.
163 - bool apply(Rewriter &Rewrite) const;
165 - /// \brief Returns a human readable string representation.
166 - std::string toString() const;
169 - void setFromSourceLocation(const SourceManager &Sources,
170 - SourceLocation Start, unsigned Length,
171 - StringRef ReplacementText);
172 - void setFromSourceRange(const SourceManager &Sources,
173 - const CharSourceRange &Range,
174 - StringRef ReplacementText,
175 - const LangOptions &LangOpts);
177 - std::string FilePath;
178 - Range ReplacementRange;
179 - std::string ReplacementText;
182 -/// \brief Less-than operator between two Replacements.
183 -bool operator<(const Replacement &LHS, const Replacement &RHS);
185 -/// \brief Equal-to operator between two Replacements.
186 -bool operator==(const Replacement &LHS, const Replacement &RHS);
188 -/// \brief A set of Replacements.
189 -/// FIXME: Change to a vector and deduplicate in the RefactoringTool.
190 -typedef std::set<Replacement> Replacements;
192 -/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
194 -/// Replacement applications happen independently of the success of
195 -/// other applications.
197 -/// \returns true if all replacements apply. false otherwise.
198 -bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite);
200 -/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite.
202 -/// Replacement applications happen independently of the success of
203 -/// other applications.
205 -/// \returns true if all replacements apply. false otherwise.
206 -bool applyAllReplacements(const std::vector<Replacement> &Replaces,
207 - Rewriter &Rewrite);
209 -/// \brief Applies all replacements in \p Replaces to \p Code.
211 -/// This completely ignores the path stored in each replacement. If all
212 -/// replacements are applied successfully, this returns the code with
213 -/// replacements applied; otherwise, an llvm::Error carrying llvm::StringError
214 -/// is returned (the Error message can be converted to string using
215 -/// `llvm::toString()` and 'std::error_code` in the `Error` should be ignored).
216 -llvm::Expected<std::string> applyAllReplacements(StringRef Code,
217 - const Replacements &Replaces);
219 -/// \brief Calculates how a code \p Position is shifted when \p Replaces are
221 -unsigned shiftedCodePosition(const Replacements& Replaces, unsigned Position);
223 -/// \brief Calculates how a code \p Position is shifted when \p Replaces are
226 -/// \pre Replaces[i].getOffset() <= Replaces[i+1].getOffset().
227 -unsigned shiftedCodePosition(const std::vector<Replacement> &Replaces,
228 - unsigned Position);
230 -/// \brief Removes duplicate Replacements and reports if Replacements conflict
231 -/// with one another. All Replacements are assumed to be in the same file.
233 -/// \post Replaces[i].getOffset() <= Replaces[i+1].getOffset().
235 -/// This function sorts \p Replaces so that conflicts can be reported simply by
236 -/// offset into \p Replaces and number of elements in the conflict.
237 -void deduplicate(std::vector<Replacement> &Replaces,
238 - std::vector<Range> &Conflicts);
240 -/// \brief Collection of Replacements generated from a single translation unit.
241 -struct TranslationUnitReplacements {
242 - /// Name of the main source for the translation unit.
243 - std::string MainSourceFile;
245 - /// A freeform chunk of text to describe the context of the replacements.
246 - /// Will be printed, for example, when detecting conflicts during replacement
248 - std::string Context;
250 - std::vector<Replacement> Replacements;
253 -/// \brief Calculates the ranges in a single file that are affected by the
254 -/// Replacements. Overlapping ranges will be merged.
256 -/// \pre Replacements must be for the same file.
258 -/// \returns a non-overlapping and sorted ranges.
259 -std::vector<Range> calculateChangedRanges(const Replacements &Replaces);
261 -/// \brief Calculates the new ranges after \p Replaces are applied. These
262 -/// include both the original \p Ranges and the affected ranges of \p Replaces
263 -/// in the new code.
265 -/// \pre Replacements must be for the same file.
267 -/// \return The new ranges after \p Replaces are applied. The new ranges will be
268 -/// sorted and non-overlapping.
270 -calculateRangesAfterReplacements(const Replacements &Replaces,
271 - const std::vector<Range> &Ranges);
273 -/// \brief Groups a random set of replacements by file path. Replacements
274 -/// related to the same file entry are put into the same vector.
275 -std::map<std::string, Replacements>
276 -groupReplacementsByFile(const Replacements &Replaces);
278 -/// \brief Merges two sets of replacements with the second set referring to the
279 -/// code after applying the first set. Within both 'First' and 'Second',
280 -/// replacements must not overlap.
281 -Replacements mergeReplacements(const Replacements &First,
282 - const Replacements &Second);
284 -template <typename Node>
285 -Replacement::Replacement(const SourceManager &Sources,
286 - const Node &NodeToReplace, StringRef ReplacementText,
287 - const LangOptions &LangOpts) {
288 - const CharSourceRange Range =
289 - CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
290 - setFromSourceRange(Sources, Range, ReplacementText, LangOpts);
291 + struct TranslationUnitDiagnostics {
292 + std::string MainSourceFile;
293 + std::string Context;
294 + std::vector<Diagnostics> Diags;
299 -} // end namespace tooling
300 -} // end namespace clang
302 -#endif // LLVM_CLANG_TOOLING_CORE_REPLACEMENT_H
304 \ No newline at end of file
305 Index: lib/Tooling/Core/CMakeLists.txt
306 ===================================================================
307 --- lib/Tooling/Core/CMakeLists.txt (revision 278390)
308 +++ lib/Tooling/Core/CMakeLists.txt (working copy)
310 add_clang_library(clangToolingCore
317 Index: lib/Tooling/Core/Diagnostics.cpp
318 ===================================================================
319 --- lib/Tooling/Core/Diagnostics.cpp (revision 278390)
320 +++ lib/Tooling/Core/Diagnostics.cpp (working copy)
322 -//===--- Lookup.cpp - Framework for clang refactoring tools ---------------===//
324 -// The LLVM Compiler Infrastructure
326 -// This file is distributed under the University of Illinois Open Source
327 -// License. See LICENSE.TXT for details.
329 -//===----------------------------------------------------------------------===//
331 -// This file defines helper methods for clang tools performing name lookup.
333 -//===----------------------------------------------------------------------===//
334 +#include "clang/Tooling/Core/Diagnostics.h"
335 +#include "clang/Basic/SourceManager.h"
337 + namespace tooling {
339 -#include "clang/Tooling/Core/Lookup.h"
340 -#include "clang/AST/Decl.h"
341 -using namespace clang;
342 -using namespace clang::tooling;
343 + DiagnosticsMessage::DiagnosticsMessage(StringRef Message)
344 + : Message(Message), FileOffset(0) {
347 -static bool isInsideDifferentNamespaceWithSameName(const DeclContext *DeclA,
348 - const DeclContext *DeclB) {
350 - // Look past non-namespaces on DeclA.
351 - while (DeclA && !isa<NamespaceDecl>(DeclA))
352 - DeclA = DeclA->getParent();
353 + DiagnosticsMessage::DiagnosticsMessage(StringRef Message,
354 + const SourceManager &Sources,
355 + SourceLocation Loc)
356 + : Message(Message) {
357 + assert(Loc.isValid() && Loc.isFileID());
358 + FilePath = Sources.getFilename(Loc);
359 + FileOffset = Sources.getFileOffset(Loc);
362 - // Look past non-namespaces on DeclB.
363 - while (DeclB && !isa<NamespaceDecl>(DeclB))
364 - DeclB = DeclB->getParent();
365 + Diagnostics::Diagnostics() {
368 - // We hit the root, no namespace collision.
369 - if (!DeclA || !DeclB)
372 - // Literally the same namespace, not a collision.
373 - if (DeclA == DeclB)
376 - // Now check the names. If they match we have a different namespace with the
378 - if (cast<NamespaceDecl>(DeclA)->getDeclName() ==
379 - cast<NamespaceDecl>(DeclB)->getDeclName())
382 - DeclA = DeclA->getParent();
383 - DeclB = DeclB->getParent();
387 -static StringRef getBestNamespaceSubstr(const DeclContext *DeclA,
389 - bool HadLeadingColonColon) {
391 - while (DeclA && !isa<NamespaceDecl>(DeclA))
392 - DeclA = DeclA->getParent();
394 - // Fully qualified it is! Leave :: in place if it's there already.
396 - return HadLeadingColonColon ? NewName : NewName.substr(2);
398 - // Otherwise strip off redundant namespace qualifications from the new name.
399 - // We use the fully qualified name of the namespace and remove that part
400 - // from NewName if it has an identical prefix.
402 - "::" + cast<NamespaceDecl>(DeclA)->getQualifiedNameAsString() + "::";
403 - if (NewName.startswith(NS))
404 - return NewName.substr(NS.size());
406 - // No match yet. Strip of a namespace from the end of the chain and try
407 - // again. This allows to get optimal qualifications even if the old and new
408 - // decl only share common namespaces at a higher level.
409 - DeclA = DeclA->getParent();
413 -/// Check if the name specifier begins with a written "::".
414 -static bool isFullyQualified(const NestedNameSpecifier *NNS) {
416 - if (NNS->getKind() == NestedNameSpecifier::Global)
418 - NNS = NNS->getPrefix();
423 -std::string tooling::replaceNestedName(const NestedNameSpecifier *Use,
424 - const DeclContext *UseContext,
425 - const NamedDecl *FromDecl,
426 - StringRef ReplacementString) {
427 - assert(ReplacementString.startswith("::") &&
428 - "Expected fully-qualified name!");
430 - // We can do a raw name replacement when we are not inside the namespace for
431 - // the original function and it is not in the global namespace. The
432 - // assumption is that outside the original namespace we must have a using
433 - // statement that makes this work out and that other parts of this refactor
434 - // will automatically fix using statements to point to the new function
435 - const bool class_name_only = !Use;
436 - const bool in_global_namespace =
437 - isa<TranslationUnitDecl>(FromDecl->getDeclContext());
438 - if (class_name_only && !in_global_namespace &&
439 - !isInsideDifferentNamespaceWithSameName(FromDecl->getDeclContext(),
441 - auto Pos = ReplacementString.rfind("::");
442 - return Pos != StringRef::npos ? ReplacementString.substr(Pos + 2)
443 - : ReplacementString;
445 - // We did not match this because of a using statement, so we will need to
446 - // figure out how good a namespace match we have with our destination type.
447 - // We work backwards (from most specific possible namespace to least
449 - return getBestNamespaceSubstr(UseContext, ReplacementString,
450 - isFullyQualified(Use));
452 + Diagnostics::Diagnostics(StringRef CheckName,
453 + Diagnostics::Level DiagLevel,
454 + bool IsWarningAsError,
455 + StringRef BuildDirectory)
456 + : CheckName(CheckName), BuildDirectory(BuildDirectory), DiagLevel(DiagLevel),
457 + IsWarningAsError(IsWarningAsError) {
461 \ No newline at end of file