Esempio n. 1
0
  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);
  }
Esempio n. 2
0
  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();
  }