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