void HandleOneRename(ASTContext &Context, const std::string &NewName, const std::string &PrevName, const std::vector<std::string> &USRs) { const SourceManager &SourceMgr = Context.getSourceManager(); SymbolOccurrences Occurrences = tooling::getOccurrencesOfUSRs( USRs, PrevName, Context.getTranslationUnitDecl()); 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: 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); }
void HandleTranslationUnit(ASTContext &Context) override { const auto &SourceMgr = Context.getSourceManager(); std::vector<SourceLocation> RenamingCandidates; std::vector<SourceLocation> NewCandidates; for (const auto &USR : USRs) { NewCandidates = getLocationsOfUSR(USR, Context.getTranslationUnitDecl()); RenamingCandidates.insert(RenamingCandidates.end(), NewCandidates.begin(), NewCandidates.end()); NewCandidates.clear(); } auto PrevNameLen = PrevName.length(); if (PrintLocations) for (const auto &Loc : RenamingCandidates) { FullSourceLoc FullLoc(Loc, SourceMgr); errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(Loc) << ":" << FullLoc.getSpellingLineNumber() << ":" << FullLoc.getSpellingColumnNumber() << "\n"; Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen, NewName)); } else for (const auto &Loc : RenamingCandidates) Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen, NewName)); }
bool FindSymbol(ASTContext &Context, const SourceManager &SourceMgr, unsigned SymbolOffset, const std::string &QualifiedName) { DiagnosticsEngine &Engine = Context.getDiagnostics(); const SourceLocation Point = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()) .getLocWithOffset(SymbolOffset); if (!Point.isValid()) { ErrorOccurred = true; unsigned InvalidOffset = Engine.getCustomDiagID( DiagnosticsEngine::Error, "SourceLocation in file %0 at offset %1 is invalid"); Engine.Report(Point, InvalidOffset) << SourceMgr.getFilename(Point) << SymbolOffset; return false; } const NamedDecl *FoundDecl = QualifiedName.empty() ? getNamedDeclAt(Context, Point) : getNamedDeclFor(Context, QualifiedName); if (FoundDecl == nullptr) { if (QualifiedName.empty()) { FullSourceLoc FullLoc(Point, SourceMgr); unsigned CouldNotFindSymbolAt = Engine.getCustomDiagID( DiagnosticsEngine::Error, "clang-rename could not find symbol (offset %0)"); Engine.Report(Point, CouldNotFindSymbolAt) << SymbolOffset; ErrorOccurred = true; return false; } unsigned CouldNotFindSymbolNamed = Engine.getCustomDiagID( DiagnosticsEngine::Error, "clang-rename could not find symbol %0"); Engine.Report(CouldNotFindSymbolNamed) << QualifiedName; ErrorOccurred = true; return false; } // If FoundDecl is a constructor or destructor, we want to instead take // the Decl of the corresponding class. if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl)) FoundDecl = CtorDecl->getParent(); else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl)) FoundDecl = DtorDecl->getParent(); SpellingNames.push_back(FoundDecl->getNameAsString()); AdditionalUSRFinder Finder(FoundDecl, Context); USRList.push_back(Finder.Find()); return true; }
void HandleTranslationUnit(ASTContext &Context) override { const auto &SourceMgr = Context.getSourceManager(); // The file we look for the USR in will always be the main source file. const auto Point = SourceMgr.getLocForStartOfFile( SourceMgr.getMainFileID()).getLocWithOffset(SymbolOffset); if (!Point.isValid()) return; const NamedDecl *FoundDecl = nullptr; if (OldName.empty()) { FoundDecl = getNamedDeclAt(Context, Point); } else { FoundDecl = getNamedDeclFor(Context, OldName); } if (FoundDecl == nullptr) { FullSourceLoc FullLoc(Point, SourceMgr); errs() << "clang-rename: could not find symbol at " << SourceMgr.getFilename(Point) << ":" << FullLoc.getSpellingLineNumber() << ":" << FullLoc.getSpellingColumnNumber() << " (offset " << SymbolOffset << ").\n"; return; } // If the decl is a constructor or destructor, we want to instead take the // decl of the parent record. if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl)) FoundDecl = CtorDecl->getParent(); else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl)) FoundDecl = DtorDecl->getParent(); // If the decl is in any way relatedpp to a class, we want to make sure we // search for the constructor and destructor as well as everything else. if (const auto *Record = dyn_cast<CXXRecordDecl>(FoundDecl)) *USRs = getAllConstructorUSRs(Record); USRs->push_back(getUSRForDecl(FoundDecl)); *SpellingName = FoundDecl->getNameAsString(); }
void HandleTranslationUnit(ASTContext &Context) override { const SourceManager &SourceMgr = Context.getSourceManager(); // The file we look for the USR in will always be the main source file. const SourceLocation Point = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()) .getLocWithOffset(SymbolOffset); if (!Point.isValid()) return; const NamedDecl *FoundDecl = nullptr; if (OldName.empty()) { FoundDecl = getNamedDeclAt(Context, Point); } else { FoundDecl = getNamedDeclFor(Context, OldName); } if (FoundDecl == nullptr) { FullSourceLoc FullLoc(Point, SourceMgr); errs() << "clang-rename: could not find symbol at " << SourceMgr.getFilename(Point) << ":" << FullLoc.getSpellingLineNumber() << ":" << FullLoc.getSpellingColumnNumber() << " (offset " << SymbolOffset << ").\n"; return; } // If FoundDecl is a constructor or destructor, we want to instead take the // Decl of the corresponding class. if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl)) { FoundDecl = CtorDecl->getParent(); } else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl)) { FoundDecl = DtorDecl->getParent(); } *SpellingName = FoundDecl->getNameAsString(); AdditionalUSRFinder Finder(FoundDecl, Context, USRs); Finder.Find(); }