<div dir="ltr">It's an NFC, thus untested.<div class="gmail_extra"><br><div class="gmail_quote">On 14 August 2017 at 17:19, Alex Lorenz via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: arphaman<br>
Date: Mon Aug 14 09:19:24 2017<br>
New Revision: 310853<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=310853&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=310853&view=rev</a><br>
Log:<br>
[rename] Introduce symbol occurrences<br>
<br>
Symbol occurrences store the results of local rename and will also be used for<br>
the global, indexed rename results. Their kind is used to determine whether they<br>
should be renamed automatically or not. They can be converted to a set of<br>
AtomicChanges as well.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D36156" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D36156</a><br>
<br>
Added:<br>
    cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>SymbolName.h<br>
    cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>SymbolOccurrences.h<br>
    cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>SymbolOccurrences.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>RenamingAction.h<br>
    cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>USRLocFinder.h<br>
    cfe/trunk/lib/Tooling/<wbr>Refactoring/CMakeLists.txt<br>
    cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>RenamingAction.cpp<br>
    cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>USRLocFinder.cpp<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>RenamingAction.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Rename/RenamingAction.h?rev=310853&r1=310852&r2=310853&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Tooling/Refactoring/<wbr>Rename/RenamingAction.h?rev=<wbr>310853&r1=310852&r2=310853&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>RenamingAction.h (original)<br>
+++ cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>RenamingAction.h Mon Aug 14 09:19:24 2017<br>
@@ -16,6 +16,9 @@<br>
 #define LLVM_CLANG_TOOLING_REFACTOR_<wbr>RENAME_RENAMING_ACTION_H<br>
<br>
 #include "clang/Tooling/Refactoring.h"<br>
+#include "clang/Tooling/Refactoring/<wbr>AtomicChange.h"<br>
+#include "clang/Tooling/Refactoring/<wbr>Rename/SymbolOccurrences.h"<br>
+#include "llvm/Support/Error.h"<br>
<br>
 namespace clang {<br>
 class ASTConsumer;<br>
@@ -42,6 +45,13 @@ private:<br>
   bool PrintLocations;<br>
 };<br>
<br>
+/// Returns source replacements that correspond to the rename of the given<br>
+/// symbol occurrences.<br>
+llvm::Expected<std::vector<<wbr>AtomicChange>><br>
+createRenameReplacements(<wbr>const SymbolOccurrences &Occurrences,<br>
+                         const SourceManager &SM,<br>
+                         ArrayRef<StringRef> NewNameStrings);<br>
+<br>
 /// Rename all symbols identified by the given USRs.<br>
 class QualifiedRenamingAction {<br>
 public:<br>
<br>
Added: cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>SymbolName.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h?rev=310853&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Tooling/Refactoring/<wbr>Rename/SymbolName.h?rev=<wbr>310853&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>SymbolName.h (added)<br>
+++ cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>SymbolName.h Mon Aug 14 09:19:24 2017<br>
@@ -0,0 +1,49 @@<br>
+//===--- SymbolName.h - Clang refactoring library -------------------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_<wbr>RENAME_SYMBOL_NAME_H<br>
+#define LLVM_CLANG_TOOLING_REFACTOR_<wbr>RENAME_SYMBOL_NAME_H<br>
+<br>
+#include "clang/Basic/LLVM.h"<br>
+#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/ADT/SmallVector.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+<br>
+namespace clang {<br>
+namespace tooling {<br>
+<br>
+/// A name of a symbol.<br>
+///<br>
+/// Symbol's name can be composed of multiple strings. For example, Objective-C<br>
+/// methods can contain multiple argument lables:<br>
+///<br>
+/// \code<br>
+/// - (void) myMethodNamePiece: (int)x anotherNamePieces:(int)y;<br>
+/// //       ^~ string 0 ~~~~~         ^~ string 1 ~~~~~<br>
+/// \endcode<br>
+class SymbolName {<br>
+public:<br>
+  SymbolName(StringRef Name) {<br>
+    // While empty symbol names are valid (Objective-C selectors can have empty<br>
+    // name pieces), occurrences Objective-C selectors are created using an<br>
+    // array of strings instead of just one string.<br>
+    assert(!Name.empty() && "Invalid symbol name!");<br>
+    this->Name.push_back(Name.str(<wbr>));<br>
+  }<br>
+<br>
+  ArrayRef<std::string> getNamePieces() const { return Name; }<br>
+<br>
+private:<br>
+  llvm::SmallVector<std::string, 1> Name;<br>
+};<br>
+<br>
+} // end namespace tooling<br>
+} // end namespace clang<br>
+<br>
+#endif // LLVM_CLANG_TOOLING_REFACTOR_<wbr>RENAME_SYMBOL_NAME_H<br>
<br>
Added: cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>SymbolOccurrences.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h?rev=310853&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Tooling/Refactoring/<wbr>Rename/SymbolOccurrences.h?<wbr>rev=310853&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>SymbolOccurrences.h (added)<br>
+++ cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>SymbolOccurrences.h Mon Aug 14 09:19:24 2017<br>
@@ -0,0 +1,91 @@<br>
+//===--- SymbolOccurrences.h - Clang refactoring library ------------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_<wbr>RENAME_SYMBOL_OCCURRENCES_H<br>
+#define LLVM_CLANG_TOOLING_REFACTOR_<wbr>RENAME_SYMBOL_OCCURRENCES_H<br>
+<br>
+#include "clang/Basic/LLVM.h"<br>
+#include "clang/Basic/SourceLocation.h"<br>
+#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include <vector><br>
+<br>
+namespace clang {<br>
+namespace tooling {<br>
+<br>
+class SymbolName;<br>
+<br>
+/// An occurrence of a symbol in the source.<br>
+///<br>
+/// Occurrences can have difference kinds, that describe whether this occurrence<br>
+/// is an exact semantic match, or whether this is a weaker textual match that's<br>
+/// not guaranteed to represent the exact declaration.<br>
+///<br>
+/// A single occurrence of a symbol can span more than one source range. For<br>
+/// example, Objective-C selectors can contain multiple argument labels:<br>
+///<br>
+/// \code<br>
+/// [object selectorPiece1: ... selectorPiece2: ...];<br>
+/// //      ^~~ range 0 ~~      ^~~ range 1 ~~<br>
+/// \endcode<br>
+///<br>
+/// We have to replace the text in both range 0 and range 1 when renaming the<br>
+/// Objective-C method 'selectorPiece1:<wbr>selectorPiece2'.<br>
+class SymbolOccurrence {<br>
+public:<br>
+  enum OccurrenceKind {<br>
+    /// This occurrence is an exact match and can be renamed automatically.<br>
+    ///<br>
+    /// Note:<br>
+    /// Symbol occurrences in macro arguments that expand to different<br>
+    /// declarations get marked as exact matches, and thus the renaming engine<br>
+    /// will rename them e.g.:<br>
+    ///<br>
+    /// \code<br>
+    ///   #define MACRO(x) x + ns::x<br>
+    ///   int foo(int var) {<br>
+    ///     return MACRO(var); // var is renamed automatically here when<br>
+    ///                        // either var or ns::var is renamed.<br>
+    ///   };<br>
+    /// \endcode<br>
+    ///<br>
+    /// The user will have to fix their code manually after performing such a<br>
+    /// rename.<br>
+    /// FIXME: The rename verifier should notify user about this issue.<br>
+    MatchingSymbol<br>
+  };<br>
+<br>
+  SymbolOccurrence(const SymbolName &Name, OccurrenceKind Kind,<br>
+                   ArrayRef<SourceLocation> Locations);<br>
+<br>
+  SymbolOccurrence(<wbr>SymbolOccurrence &&) = default;<br>
+  SymbolOccurrence &operator=(SymbolOccurrence &&) = default;<br>
+<br>
+  OccurrenceKind getKind() const { return Kind; }<br>
+<br>
+  ArrayRef<SourceRange> getNameRanges() const {<br>
+    if (MultipleRanges) {<br>
+      return llvm::makeArrayRef(<wbr>MultipleRanges.get(),<br>
+                                RangeOrNumRanges.getBegin().<wbr>getRawEncoding());<br>
+    }<br>
+    return RangeOrNumRanges;<br>
+  }<br>
+<br>
+private:<br>
+  OccurrenceKind Kind;<br>
+  std::unique_ptr<SourceRange[]> MultipleRanges;<br>
+  SourceRange RangeOrNumRanges;<br>
+};<br>
+<br>
+using SymbolOccurrences = std::vector<SymbolOccurrence>;<br>
+<br>
+} // end namespace tooling<br>
+} // end namespace clang<br>
+<br>
+#endif // LLVM_CLANG_TOOLING_REFACTOR_<wbr>RENAME_SYMBOL_OCCURRENCES_H<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>USRLocFinder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h?rev=310853&r1=310852&r2=310853&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Tooling/Refactoring/<wbr>Rename/USRLocFinder.h?rev=<wbr>310853&r1=310852&r2=310853&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>USRLocFinder.h (original)<br>
+++ cfe/trunk/include/clang/<wbr>Tooling/Refactoring/Rename/<wbr>USRLocFinder.h Mon Aug 14 09:19:24 2017<br>
@@ -19,6 +19,7 @@<br>
 #include "clang/AST/AST.h"<br>
 #include "clang/Tooling/Core/<wbr>Replacement.h"<br>
 #include "clang/Tooling/Refactoring/<wbr>AtomicChange.h"<br>
+#include "clang/Tooling/Refactoring/<wbr>Rename/SymbolOccurrences.h"<br>
 #include "llvm/ADT/StringRef.h"<br>
 #include <string><br>
 #include <vector><br>
@@ -38,10 +39,13 @@ std::vector<tooling::<wbr>AtomicChange><br>
 createRenameAtomicChanges(<wbr>llvm::ArrayRef<std::string> USRs,<br>
                           llvm::StringRef NewName, Decl *TranslationUnitDecl);<br>
<br>
-// FIXME: make this an AST matcher. Wouldn't that be awesome??? I agree!<br>
-std::vector<SourceLocation><br>
-getLocationsOfUSRs(const std::vector<std::string> &USRs,<br>
-                   llvm::StringRef PrevName, Decl *Decl);<br>
+/// Finds the symbol occurrences for the symbol that's identified by the given<br>
+/// USR set.<br>
+///<br>
+/// \return SymbolOccurrences that can be converted to AtomicChanges when<br>
+/// renaming.<br>
+SymbolOccurrences getOccurrencesOfUSRs(ArrayRef<<wbr>std::string> USRs,<br>
+                                       StringRef PrevName, Decl *Decl);<br>
<br>
 } // end namespace tooling<br>
 } // end namespace clang<br>
<br>
Modified: cfe/trunk/lib/Tooling/<wbr>Refactoring/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt?rev=310853&r1=310852&r2=310853&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Tooling/<wbr>Refactoring/CMakeLists.txt?<wbr>rev=310853&r1=310852&r2=<wbr>310853&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Tooling/<wbr>Refactoring/CMakeLists.txt (original)<br>
+++ cfe/trunk/lib/Tooling/<wbr>Refactoring/CMakeLists.txt Mon Aug 14 09:19:24 2017<br>
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS Support)<br>
 add_clang_library(<wbr>clangToolingRefactor<br>
   AtomicChange.cpp<br>
   Rename/RenamingAction.cpp<br>
+  Rename/SymbolOccurrences.cpp<br>
   Rename/USRFinder.cpp<br>
   Rename/USRFindingAction.cpp<br>
   Rename/USRLocFinder.cpp<br>
<br>
Modified: cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>RenamingAction.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp?rev=310853&r1=310852&r2=310853&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>RenamingAction.cpp?rev=310853&<wbr>r1=310852&r2=310853&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>RenamingAction.cpp (original)<br>
+++ cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>RenamingAction.cpp Mon Aug 14 09:19:24 2017<br>
@@ -24,6 +24,7 @@<br>
 #include "clang/Tooling/Refactoring.h"<br>
 #include "clang/Tooling/Refactoring/<wbr>Rename/USRLocFinder.h"<br>
 #include "clang/Tooling/Tooling.h"<br>
+#include "llvm/ADT/STLExtras.h"<br>
 #include <string><br>
 #include <vector><br>
<br>
@@ -32,6 +33,45 @@ using namespace llvm;<br>
 namespace clang {<br>
 namespace tooling {<br>
<br>
+Expected<std::vector<<wbr>AtomicChange>><br>
+createRenameReplacements(<wbr>const SymbolOccurrences &Occurrences,<br>
+                         const SourceManager &SM,<br>
+                         ArrayRef<StringRef> NewNameStrings) {<br>
+  // FIXME: A true local rename can use just one AtomicChange.<br>
+  std::vector<AtomicChange> Changes;<br>
+  for (const auto &Occurrence : Occurrences) {<br>
+    ArrayRef<SourceRange> Ranges = Occurrence.getNameRanges();<br>
+    assert(NewNameStrings.size() == Ranges.size() &&<br>
+           "Mismatching number of ranges and name pieces");<br>
+    AtomicChange Change(SM, Ranges[0].getBegin());<br>
+    for (const auto &Range : llvm::enumerate(Ranges)) {<br>
+      auto Error =<br>
+          Change.replace(SM, CharSourceRange::getCharRange(<wbr>Range.value()),<br>
+                         NewNameStrings[Range.index()])<wbr>;<br>
+      if (Error)<br>
+        return std::move(Error);<br>
+    }<br>
+    Changes.push_back(std::move(<wbr>Change));<br>
+  }<br>
+  return Changes;<br>
+}<br>
+<br>
+/// Takes each atomic change and inserts its replacements into the set of<br>
+/// replacements that belong to the appropriate file.<br>
+static void convertChangesToFileReplacemen<wbr>ts(<br>
+    ArrayRef<AtomicChange> AtomicChanges,<br>
+    std::map<std::string, tooling::Replacements> *FileToReplaces) {<br>
+  for (const auto &AtomicChange : AtomicChanges) {<br>
+    for (const auto &Replace : AtomicChange.getReplacements()<wbr>) {<br>
+      llvm::Error Err = (*FileToReplaces)[Replace.<wbr>getFilePath()].add(Replace);<br>
+      if (Err) {<br>
+        llvm::errs() << "Renaming failed in " << Replace.getFilePath() << "! "<br>
+                     << llvm::toString(std::move(Err)) << "\n";<br>
+      }<br>
+    }<br>
+  }<br>
+}<br>
+<br>
 class RenamingASTConsumer : public ASTConsumer {<br>
 public:<br>
   RenamingASTConsumer(<br>
@@ -52,29 +92,29 @@ public:<br>
                        const std::string &PrevName,<br>
                        const std::vector<std::string> &USRs) {<br>
     const SourceManager &SourceMgr = Context.getSourceManager();<br>
-    std::vector<SourceLocation> RenamingCandidates;<br>
-    std::vector<SourceLocation> NewCandidates;<br>
<br>
-    NewCandidates = tooling::getLocationsOfUSRs(<br>
+    SymbolOccurrences Occurrences = tooling::getOccurrencesOfUSRs(<br>
         USRs, PrevName, Context.<wbr>getTranslationUnitDecl());<br>
-    RenamingCandidates.insert(<wbr>RenamingCandidates.end(), NewCandidates.begin(),<br>
-                              NewCandidates.end());<br>
-<br>
-    unsigned PrevNameLen = PrevName.length();<br>
-    for (const auto &Loc : RenamingCandidates) {<br>
-      if (PrintLocations) {<br>
-        FullSourceLoc FullLoc(Loc, SourceMgr);<br>
-        errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(Loc)<br>
+    if (PrintLocations) {<br>
+      for (const auto &Occurrence : Occurrences) {<br>
+        FullSourceLoc FullLoc(Occurrence.<wbr>getNameRanges()[0].getBegin(),<br>
+                              SourceMgr);<br>
+        errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(FullLoc)<br>
                << ":" << FullLoc.getSpellingLineNumber(<wbr>) << ":"<br>
                << FullLoc.<wbr>getSpellingColumnNumber() << "\n";<br>
       }<br>
-      // FIXME: better error handling.<br>
-      tooling::Replacement Replace(SourceMgr, Loc, PrevNameLen, NewName);<br>
-      llvm::Error Err = FileToReplaces[Replace.<wbr>getFilePath()].add(Replace);<br>
-      if (Err)<br>
-        llvm::errs() << "Renaming failed in " << Replace.getFilePath() << "! "<br>
-                     << llvm::toString(std::move(Err)) << "\n";<br>
     }<br>
+    // FIXME: Support multi-piece names.<br>
+    // FIXME: better error handling (propagate error out).<br>
+    StringRef NewNameRef = NewName;<br>
+    Expected<std::vector<<wbr>AtomicChange>> Change =<br>
+        createRenameReplacements(<wbr>Occurrences, SourceMgr, NewNameRef);<br>
+    if (!Change) {<br>
+      llvm::errs() << "Failed to create renaming replacements for '" << PrevName<br>
+                   << "'! " << llvm::toString(Change.<wbr>takeError()) << "\n";<br>
+      return;<br>
+    }<br>
+    convertChangesToFileReplacemen<wbr>ts(*Change, &FileToReplaces);<br>
   }<br>
<br>
 private:<br>
@@ -103,15 +143,7 @@ public:<br>
       // ready.<br>
       auto AtomicChanges = tooling::<wbr>createRenameAtomicChanges(<br>
           USRList[I], NewNames[I], Context.<wbr>getTranslationUnitDecl());<br>
-      for (const auto AtomicChange : AtomicChanges) {<br>
-        for (const auto &Replace : AtomicChange.getReplacements()<wbr>) {<br>
-          llvm::Error Err = FileToReplaces[Replace.<wbr>getFilePath()].add(Replace);<br>
-          if (Err) {<br>
-            llvm::errs() << "Renaming failed in " << Replace.getFilePath()<br>
-                         << "! " << llvm::toString(std::move(Err)) << "\n";<br>
-          }<br>
-        }<br>
-      }<br>
+      convertChangesToFileReplacemen<wbr>ts(AtomicChanges, &FileToReplaces);<br>
     }<br>
   }<br>
<br>
<br>
Added: cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>SymbolOccurrences.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp?rev=310853&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>SymbolOccurrences.cpp?rev=<wbr>310853&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>SymbolOccurrences.cpp (added)<br>
+++ cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>SymbolOccurrences.cpp Mon Aug 14 09:19:24 2017<br>
@@ -0,0 +1,37 @@<br>
+//===--- SymbolOccurrences.cpp - Clang refactoring library ----------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#include "clang/Tooling/Refactoring/<wbr>Rename/SymbolOccurrences.h"<br>
+#include "clang/Tooling/Refactoring/<wbr>Rename/SymbolName.h"<br>
+#include "llvm/ADT/STLExtras.h"<br>
+<br>
+using namespace clang;<br>
+using namespace tooling;<br>
+<br>
+SymbolOccurrence::<wbr>SymbolOccurrence(const SymbolName &Name, OccurrenceKind Kind,<br>
+                                   ArrayRef<SourceLocation> Locations)<br>
+    : Kind(Kind) {<br>
+  ArrayRef<std::string> NamePieces = Name.getNamePieces();<br>
+  assert(Locations.size() == NamePieces.size() &&<br>
+         "mismatching number of locations and lengths");<br>
+  assert(!Locations.empty() && "no locations");<br>
+  if (Locations.size() == 1) {<br>
+    RangeOrNumRanges = SourceRange(<br>
+        Locations[0], Locations[0].getLocWithOffset(<wbr>NamePieces[0].size()));<br>
+    return;<br>
+  }<br>
+  MultipleRanges = llvm::make_unique<SourceRange[<wbr>]>(Locations.size());<br>
+  RangeOrNumRanges.setBegin(<br>
+      SourceLocation::<wbr>getFromRawEncoding(Locations.<wbr>size()));<br>
+  for (const auto &Loc : llvm::enumerate(Locations)) {<br>
+    MultipleRanges[Loc.index()] = SourceRange(<br>
+        Loc.value(),<br>
+        Loc.value().getLocWithOffset(<wbr>NamePieces[Loc.index()].size()<wbr>));<br>
+  }<br>
+}<br>
<br>
Modified: cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>USRLocFinder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp?rev=310853&r1=310852&r2=310853&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>USRLocFinder.cpp?rev=310853&<wbr>r1=310852&r2=310853&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>USRLocFinder.cpp (original)<br>
+++ cfe/trunk/lib/Tooling/<wbr>Refactoring/Rename/<wbr>USRLocFinder.cpp Mon Aug 14 09:19:24 2017<br>
@@ -23,6 +23,7 @@<br>
 #include "clang/Lex/Lexer.h"<br>
 #include "clang/Tooling/Core/Lookup.h"<br>
 #include "clang/Tooling/Refactoring/<wbr>RecursiveSymbolVisitor.h"<br>
+#include "clang/Tooling/Refactoring/<wbr>Rename/SymbolName.h"<br>
 #include "clang/Tooling/Refactoring/<wbr>Rename/USRFinder.h"<br>
 #include "llvm/ADT/StringRef.h"<br>
 #include "llvm/Support/Casting.h"<br>
@@ -68,11 +69,9 @@ public:<br>
<br>
   // Non-visitors:<br>
<br>
-  // \brief Returns a list of unique locations. Duplicate or overlapping<br>
-  // locations are erroneous and should be reported!<br>
-  const std::vector<clang::<wbr>SourceLocation> &getLocationsFound() const {<br>
-    return LocationsFound;<br>
-  }<br>
+  /// \brief Returns a set of unique symbol occurrences. Duplicate or<br>
+  /// overlapping occurrences are erroneous and should be reported!<br>
+  SymbolOccurrences takeOccurrences() { return std::move(Occurrences); }<br>
<br>
 private:<br>
   void checkAndAddLocation(<wbr>SourceLocation Loc) {<br>
@@ -82,17 +81,18 @@ private:<br>
     StringRef TokenName =<br>
         Lexer::getSourceText(<wbr>CharSourceRange::<wbr>getTokenRange(BeginLoc, EndLoc),<br>
                              Context.getSourceManager(), Context.getLangOpts());<br>
-    size_t Offset = TokenName.find(PrevName);<br>
+    size_t Offset = TokenName.find(PrevName.<wbr>getNamePieces()[0]);<br>
<br>
     // The token of the source location we find actually has the old<br>
     // name.<br>
     if (Offset != StringRef::npos)<br>
-      LocationsFound.push_back(<wbr>BeginLoc.getLocWithOffset(<wbr>Offset));<br>
+      Occurrences.emplace_back(<wbr>PrevName, SymbolOccurrence::<wbr>MatchingSymbol,<br>
+                               BeginLoc.getLocWithOffset(<wbr>Offset));<br>
   }<br>
<br>
   const std::set<std::string> USRSet;<br>
-  const std::string PrevName;<br>
-  std::vector<clang::<wbr>SourceLocation> LocationsFound;<br>
+  const SymbolName PrevName;<br>
+  SymbolOccurrences Occurrences;<br>
   const ASTContext &Context;<br>
 };<br>
<br>
@@ -391,12 +391,11 @@ private:<br>
<br>
 } // namespace<br>
<br>
-std::vector<SourceLocation><br>
-getLocationsOfUSRs(const std::vector<std::string> &USRs, StringRef PrevName,<br>
-                   Decl *Decl) {<br>
+SymbolOccurrences getOccurrencesOfUSRs(ArrayRef<<wbr>std::string> USRs,<br>
+                                       StringRef PrevName, Decl *Decl) {<br>
   USRLocFindingASTVisitor Visitor(USRs, PrevName, Decl->getASTContext());<br>
   Visitor.TraverseDecl(Decl);<br>
-  return Visitor.getLocationsFound();<br>
+  return Visitor.takeOccurrences();<br>
 }<br>
<br>
 std::vector<tooling::<wbr>AtomicChange><br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>