[clang-tools-extra] r215839 - First version of a clang-rename tool.

Rafael EspĂ­ndola rafael.espindola at gmail.com
Sun Aug 17 14:44:22 PDT 2014


Looks like this is failing on msvc:

http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/9983/steps/build_clang_tools/logs/stdio

On 17 August 2014 14:00, Manuel Klimek <klimek at google.com> wrote:
> Author: klimek
> Date: Sun Aug 17 13:00:59 2014
> New Revision: 215839
>
> URL: http://llvm.org/viewvc/llvm-project?rev=215839&view=rev
> Log:
> First version of a clang-rename tool.
>
> Summary:
> Note that this code is still grossly under-tested - the next steps will
> be to add significantly better test coverage.
>
> Patch by Matthew Plant.
>
> Test Plan:
>
> Reviewers:
>
> Subscribers:
>
> Added:
>     clang-tools-extra/trunk/clang-rename/
>     clang-tools-extra/trunk/clang-rename/CMakeLists.txt
>     clang-tools-extra/trunk/clang-rename/ClangRename.cpp
>     clang-tools-extra/trunk/clang-rename/Makefile
>     clang-tools-extra/trunk/clang-rename/RenamingAction.cpp
>     clang-tools-extra/trunk/clang-rename/RenamingAction.h
>     clang-tools-extra/trunk/clang-rename/USRFinder.cpp
>     clang-tools-extra/trunk/clang-rename/USRFinder.h
>     clang-tools-extra/trunk/clang-rename/USRFindingAction.cpp
>     clang-tools-extra/trunk/clang-rename/USRFindingAction.h
>     clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp
>     clang-tools-extra/trunk/clang-rename/USRLocFinder.h
>     clang-tools-extra/trunk/test/clang-rename/
>     clang-tools-extra/trunk/test/clang-rename/VarTest.cpp
>     clang-tools-extra/trunk/unittests/clang-rename/
>     clang-tools-extra/trunk/unittests/clang-rename/CMakeLists.txt
>     clang-tools-extra/trunk/unittests/clang-rename/Makefile
>     clang-tools-extra/trunk/unittests/clang-rename/USRLocFindingTest.cpp
> Modified:
>     clang-tools-extra/trunk/CMakeLists.txt
>     clang-tools-extra/trunk/Makefile
>     clang-tools-extra/trunk/test/CMakeLists.txt
>     clang-tools-extra/trunk/unittests/CMakeLists.txt
>
> Modified: clang-tools-extra/trunk/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/CMakeLists.txt?rev=215839&r1=215838&r2=215839&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/CMakeLists.txt (original)
> +++ clang-tools-extra/trunk/CMakeLists.txt Sun Aug 17 13:00:59 2014
> @@ -1,5 +1,6 @@
>  add_subdirectory(clang-apply-replacements)
>  add_subdirectory(clang-modernize)
> +add_subdirectory(clang-rename)
>  add_subdirectory(modularize)
>  add_subdirectory(module-map-checker)
>  add_subdirectory(remove-cstr-calls)
>
> Modified: clang-tools-extra/trunk/Makefile
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/Makefile?rev=215839&r1=215838&r2=215839&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/Makefile (original)
> +++ clang-tools-extra/trunk/Makefile Sun Aug 17 13:00:59 2014
> @@ -13,8 +13,8 @@ include $(CLANG_LEVEL)/../../Makefile.co
>
>  PARALLEL_DIRS := remove-cstr-calls tool-template modularize \
>   module-map-checker pp-trace
> -DIRS := clang-apply-replacements clang-modernize clang-tidy clang-query \
> -       unittests
> +DIRS := clang-apply-replacements clang-modernize clang-rename clang-tidy \
> +       clang-query unittests
>
>  include $(CLANG_LEVEL)/Makefile
>
>
> Added: clang-tools-extra/trunk/clang-rename/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/CMakeLists.txt?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/CMakeLists.txt (added)
> +++ clang-tools-extra/trunk/clang-rename/CMakeLists.txt Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,29 @@
> +set(LLVM_LINK_COMPONENTS support)
> +
> +add_clang_executable(clang-rename
> +  ClangRename.cpp
> +  USRFinder.cpp
> +  USRFindingAction.cpp
> +  USRLocFinder.cpp
> +  RenamingAction.cpp
> +  )
> +
> +target_link_libraries(clang-rename
> +  clangAnalysis
> +  clangAST
> +  clangBasic
> +  clangDriver
> +  clangEdit
> +  clangFrontend
> +  clangFrontendTool
> +  clangIndex
> +  clangLex
> +  clangParse
> +  clangRewrite
> +  clangRewriteFrontend
> +  clangSerialization
> +  clangSema
> +  clangTooling
> +  )
> +
> +install(TARGETS clang-rename RUNTIME DESTINATION bin)
> \ No newline at end of file
>
> Added: clang-tools-extra/trunk/clang-rename/ClangRename.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/ClangRename.cpp?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/ClangRename.cpp (added)
> +++ clang-tools-extra/trunk/clang-rename/ClangRename.cpp Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,151 @@
> +//===--- tools/extra/clang-rename/ClangRename.cpp - Clang rename tool -----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief This file implements a clang-rename tool that automatically finds and
> +/// renames symbols in C++ code.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "USRFindingAction.h"
> +#include "RenamingAction.h"
> +#include "clang/AST/ASTConsumer.h"
> +#include "clang/AST/ASTContext.h"
> +#include "clang/Basic/FileManager.h"
> +#include "clang/Basic/LangOptions.h"
> +#include "clang/Basic/TargetInfo.h"
> +#include "clang/Basic/TargetOptions.h"
> +#include "clang/Frontend/CommandLineSourceLoc.h"
> +#include "clang/Frontend/CompilerInstance.h"
> +#include "clang/Frontend/FrontendAction.h"
> +#include "clang/Frontend/TextDiagnosticPrinter.h"
> +#include "clang/Lex/Preprocessor.h"
> +#include "clang/Lex/Lexer.h"
> +#include "clang/Parse/Parser.h"
> +#include "clang/Parse/ParseAST.h"
> +#include "clang/Rewrite/Core/Rewriter.h"
> +#include "clang/Tooling/CommonOptionsParser.h"
> +#include "clang/Tooling/Refactoring.h"
> +#include "clang/Tooling/Tooling.h"
> +#include "llvm/ADT/IntrusiveRefCntPtr.h"
> +#include "llvm/Support/Host.h"
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <time.h>
> +#include <ctype.h>
> +#include <string>
> +#include <vector>
> +
> +using namespace llvm;
> +
> +cl::OptionCategory ClangRenameCategory("Clang-rename options");
> +
> +static cl::opt<std::string>
> +NewName(
> +    "new-name",
> +    cl::desc("The new name to change the symbol to."),
> +    cl::cat(ClangRenameCategory));
> +static cl::opt<unsigned>
> +SymbolOffset(
> +    "offset",
> +    cl::desc("Locates the symbol by offset as opposed to <line>:<column>."),
> +    cl::cat(ClangRenameCategory));
> +static cl::opt<bool>
> +Inplace(
> +    "i",
> +    cl::desc("Overwrite edited <file>s."),
> +    cl::cat(ClangRenameCategory));
> +static cl::opt<bool>
> +PrintName(
> +    "pn",
> +    cl::desc("Print the found symbol's name prior to renaming to stderr."),
> +    cl::cat(ClangRenameCategory));
> +static cl::opt<bool>
> +PrintLocations(
> +    "pl",
> +    cl::desc("Print the locations affected by renaming to stderr."),
> +    cl::cat(ClangRenameCategory));
> +
> +#define CLANG_RENAME_VERSION "0.0.1"
> +
> +static void PrintVersion() {
> +  outs() << "clang-rename version " << CLANG_RENAME_VERSION << "\n";
> +}
> +
> +using namespace clang;
> +
> +const char RenameUsage[] = "A tool to rename symbols in C/C++ code.\n\
> +clang-rename renames every occurrence of a symbol found at <offset> in\n\
> +<source0>. If -i is specified, the edited files are overwritten to disk.\n\
> +Otherwise, the results are written to stdout.\n";
> +
> +int main(int argc, const char **argv) {
> +  cl::SetVersionPrinter(PrintVersion);
> +  tooling::CommonOptionsParser OP(argc, argv, ClangRenameCategory, RenameUsage);
> +
> +  // Check the arguments for correctness.
> +
> +  if (NewName.empty()) {
> +    errs() << "clang-rename: no new name provided.\n\n";
> +    cl::PrintHelpMessage();
> +    exit(1);
> +  }
> +
> +  // Get the USRs.
> +  auto Files = OP.getSourcePathList();
> +  tooling::RefactoringTool Tool(OP.getCompilations(), Files);
> +  rename::USRFindingAction USRAction(SymbolOffset);
> +
> +  // Find the USRs.
> +  Tool.run(tooling::newFrontendActionFactory(&USRAction).get());
> +  const auto &USRs = USRAction.getUSRs();
> +  const auto &PrevName = USRAction.getUSRSpelling();
> +
> +  if (PrevName.empty())
> +    // An error should have already been printed.
> +    exit(1);
> +
> +  if (PrintName)
> +    errs() << "clang-rename: found name: " << PrevName;
> +
> +  // Perform the renaming.
> +  rename::RenamingAction RenameAction(NewName, PrevName, USRs,
> +                                      Tool.getReplacements(), PrintLocations);
> +  auto Factory = tooling::newFrontendActionFactory(&RenameAction);
> +  int res;
> +
> +  if (Inplace) {
> +    res = Tool.runAndSave(Factory.get());
> +  } else {
> +    res = Tool.run(Factory.get());
> +
> +    // Write every file to stdout. Right now we just barf the files without any
> +    // indication of which files start where, other than that we print the files
> +    // in the same order we see them.
> +    LangOptions DefaultLangOptions;
> +    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
> +        new DiagnosticOptions();
> +    TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
> +    DiagnosticsEngine Diagnostics(
> +        IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
> +        &*DiagOpts, &DiagnosticPrinter, false);
> +    auto &FileMgr = Tool.getFiles();
> +    SourceManager Sources(Diagnostics, FileMgr);
> +    Rewriter Rewrite(Sources, DefaultLangOptions);
> +
> +    Tool.applyAllReplacements(Rewrite);
> +    for (const auto &File : Files) {
> +      const auto *Entry = FileMgr.getFile(File);
> +      auto ID = Sources.translateFile(Entry);
> +      Rewrite.getEditBuffer(ID).write(outs());
> +    }
> +  }
> +
> +  exit(res);
> +}
>
> Added: clang-tools-extra/trunk/clang-rename/Makefile
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/Makefile?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/Makefile (added)
> +++ clang-tools-extra/trunk/clang-rename/Makefile Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,16 @@
> +##===- tools/extra/clang-rename/Makefile -------------------*- Makefile -*-===##
> +#
> +# The LLVM Compiler Infrastructure
> +#
> +# This file is distributed under the University of Illinois Open Source
> +# License. See LICENSE.TXT for details.
> +#
> +##===----------------------------------------------------------------------===##
> +
> +CLANG_LEVEL := ../../..
> +TOOLNAME = clang-rename
> +include $(CLANG_LEVEL)/../../Makefile.config
> +
> +DIRS = test
> +
> +include $(CLANG_LEVEL)/Makefile
>
> Added: clang-tools-extra/trunk/clang-rename/RenamingAction.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/RenamingAction.cpp?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/RenamingAction.cpp (added)
> +++ clang-tools-extra/trunk/clang-rename/RenamingAction.cpp Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,90 @@
> +//===--- tools/extra/clang-rename/RenamingAction.cpp - Clang rename tool --===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief Provides an action to rename every symbol at a point.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "RenamingAction.h"
> +#include "USRLocFinder.h"
> +#include "clang/AST/ASTConsumer.h"
> +#include "clang/AST/ASTContext.h"
> +#include "clang/Basic/FileManager.h"
> +#include "clang/Frontend/CompilerInstance.h"
> +#include "clang/Frontend/FrontendAction.h"
> +#include "clang/Lex/Preprocessor.h"
> +#include "clang/Lex/Lexer.h"
> +#include "clang/Tooling/CommonOptionsParser.h"
> +#include "clang/Tooling/Refactoring.h"
> +#include "clang/Tooling/Tooling.h"
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <ctype.h>
> +#include <string>
> +#include <vector>
> +
> +using namespace llvm;
> +
> +namespace clang {
> +namespace rename {
> +
> +class RenamingASTConsumer : public ASTConsumer {
> +public:
> +  RenamingASTConsumer(const std::string &NewName,
> +                      const std::string &PrevName,
> +                      const std::vector<std::string> &USRs,
> +                      tooling::Replacements &Replaces,
> +                      bool PrintLocations)
> +      : NewName(NewName), PrevName(PrevName), USRs(USRs), Replaces(Replaces),
> +        PrintLocations(PrintLocations) {
> +  }
> +
> +  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));
> +  }
> +
> +private:
> +  const std::string &NewName, &PrevName;
> +  const std::vector<std::string> &USRs;
> +  tooling::Replacements &Replaces;
> +  bool PrintLocations;
> +};
> +
> +std::unique_ptr<ASTConsumer> RenamingAction::newASTConsumer() {
> +  return llvm::make_unique<RenamingASTConsumer>(NewName, PrevName, USRs,
> +                                                Replaces, PrintLocations);
> +}
> +
> +}
> +}
>
> Added: clang-tools-extra/trunk/clang-rename/RenamingAction.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/RenamingAction.h?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/RenamingAction.h (added)
> +++ clang-tools-extra/trunk/clang-rename/RenamingAction.h Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,47 @@
> +//===--- tools/extra/clang-rename/RenamingAction.h - Clang rename tool ----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief Provides an action to rename every symbol at a point.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H_
> +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H_
> +
> +#include "clang/Tooling/Refactoring.h"
> +
> +namespace clang {
> +class ASTConsumer;
> +class CompilerInstance;
> +
> +namespace rename {
> +
> +class RenamingAction {
> +public:
> +  RenamingAction(const std::string &NewName, const std::string &PrevName,
> +                 const std::vector<std::string> &USRs,
> +                 tooling::Replacements &Replaces, bool PrintLocations = false)
> +      : NewName(NewName), PrevName(PrevName), USRs(USRs), Replaces(Replaces),
> +        PrintLocations(PrintLocations) {
> +  }
> +
> +  std::unique_ptr<ASTConsumer> newASTConsumer();
> +
> +private:
> +  const std::string &NewName, &PrevName;
> +  const std::vector<std::string> &USRs;
> +  tooling::Replacements &Replaces;
> +  bool PrintLocations;
> +};
> +
> +}
> +}
> +
> +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H_
>
> Added: clang-tools-extra/trunk/clang-rename/USRFinder.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/USRFinder.cpp?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/USRFinder.cpp (added)
> +++ clang-tools-extra/trunk/clang-rename/USRFinder.cpp Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,162 @@
> +//===--- tools/extra/clang-rename/USRFinder.cpp - Clang rename tool -------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file Implements a recursive AST visitor that finds the USR of a symbol at a
> +/// point.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "USRFinder.h"
> +#include "clang/AST/AST.h"
> +#include "clang/AST/ASTContext.h"
> +#include "clang/AST/RecursiveASTVisitor.h"
> +#include "clang/Lex/Lexer.h"
> +#include "clang/Index/USRGeneration.h"
> +#include "llvm/ADT/SmallVector.h"
> +
> +using namespace llvm;
> +
> +namespace clang {
> +namespace rename {
> +
> +// NamedDeclFindingASTVisitor recursively visits each AST node to find the
> +// symbol underneath the cursor.
> +// FIXME: move to seperate .h/.cc file if this gets too large.
> +namespace {
> +class NamedDeclFindingASTVisitor
> +    : public clang::RecursiveASTVisitor<NamedDeclFindingASTVisitor> {
> +public:
> +  // \brief Finds the NamedDecl at a point in the source.
> +  // \param Point the location in the source to search for the NamedDecl.
> +  explicit NamedDeclFindingASTVisitor(const SourceManager &SourceMgr,
> +                                      const SourceLocation Point)
> +      : Result(nullptr), SourceMgr(SourceMgr),
> +        Point(Point) {
> +  }
> +
> +  // Declaration visitors:
> +
> +  // \brief Checks if the point falls within the NameDecl. This covers every
> +  // declaration of a named entity that we may come across. Usually, just
> +  // checking if the point lies within the length of the name of the declaration
> +  // and the start location is sufficient.
> +  bool VisitNamedDecl(const NamedDecl *Decl) {
> +    return setResult(Decl, Decl->getLocation(),
> +                     Decl->getNameAsString().length());
> +  }
> +
> +  // Expression visitors:
> +
> +  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
> +    // Check the namespace specifier first.
> +    if (!checkNestedNameSpecifierLoc(Expr->getQualifierLoc()))
> +      return false;
> +
> +    const auto *Decl = Expr->getFoundDecl();
> +    return setResult(Decl, Expr->getLocation(),
> +                     Decl->getNameAsString().length());
> +  }
> +
> +  bool VisitMemberExpr(const MemberExpr *Expr) {
> +    const auto *Decl = Expr->getFoundDecl().getDecl();
> +    return setResult(Decl, Expr->getMemberLoc(),
> +                     Decl->getNameAsString().length());
> +  }
> +
> +  // Other:
> +
> +  const NamedDecl *getNamedDecl() {
> +    return Result;
> +  }
> +
> +private:
> +  // \brief Determines if a namespace qualifier contains the point.
> +  // \returns false on success and sets Result.
> +  bool checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
> +    while (NameLoc) {
> +      const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
> +      if (Decl && !setResult(Decl, NameLoc.getLocalBeginLoc(),
> +                             Decl->getNameAsString().length()))
> +        return false;
> +      NameLoc = NameLoc.getPrefix();
> +    }
> +    return true;
> +  }
> +
> +  // \brief Sets Result to Decl if the Point is within Start and End.
> +  // \returns false on success.
> +  bool setResult(const NamedDecl *Decl, SourceLocation Start,
> +                 SourceLocation End) {
> +    if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||
> +        !End.isFileID() || !isPointWithin(Start, End)) {
> +      return true;
> +    }
> +    Result = Decl;
> +    return false;
> +  }
> +
> +  // \brief Sets Result to Decl if Point is within Loc and Loc + Offset.
> +  // \returns false on success.
> +  bool setResult(const NamedDecl *Decl, SourceLocation Loc,
> +                 unsigned Offset) {
> +    // FIXME: Add test for Offset == 0. Add test for Offset - 1 (vs -2 etc).
> +    return Offset == 0 ||
> +           setResult(Decl, Loc, Loc.getLocWithOffset(Offset - 1));
> +  }
> +
> +  // \brief Determines if the Point is within Start and End.
> +  bool isPointWithin(const SourceLocation Start, const SourceLocation End) {
> +    // FIXME: Add tests for Point == End.
> +    return Point == Start || Point == End ||
> +           (SourceMgr.isBeforeInTranslationUnit(Start, Point) &&
> +            SourceMgr.isBeforeInTranslationUnit(Point, End));
> +  }
> +
> +  const NamedDecl *Result;
> +  const SourceManager &SourceMgr;
> +  const SourceLocation Point; // The location to find the NamedDecl.
> +};
> +}
> +
> +const NamedDecl *getNamedDeclAt(const ASTContext &Context,
> +                                const SourceLocation Point) {
> +  const auto &SourceMgr = Context.getSourceManager();
> +  const auto SearchFile = SourceMgr.getFilename(Point);
> +
> +  NamedDeclFindingASTVisitor Visitor(SourceMgr, Point);
> +
> +  // We only want to search the decls that exist in the same file as the point.
> +  auto Decls = Context.getTranslationUnitDecl()->decls();
> +  for (auto &CurrDecl : Decls) {
> +    const auto FileLoc = CurrDecl->getLocStart();
> +    const auto FileName = SourceMgr.getFilename(FileLoc);
> +    // FIXME: Add test.
> +    if (FileName == SearchFile) {
> +      Visitor.TraverseDecl(CurrDecl);
> +      if (const NamedDecl *Result = Visitor.getNamedDecl()) {
> +        return Result;
> +      }
> +    }
> +  }
> +
> +  return nullptr;
> +}
> +
> +std::string getUSRForDecl(const Decl *Decl) {
> +  llvm::SmallVector<char, 128> Buff;
> +
> +  // FIXME: Add test for the nullptr case.
> +  if (Decl == nullptr || index::generateUSRForDecl(Decl, Buff))
> +    return "";
> +
> +  return std::string(Buff.data(), Buff.size());
> +}
> +
> +} // namespace clang
> +} // namespace rename
>
> Added: clang-tools-extra/trunk/clang-rename/USRFinder.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/USRFinder.h?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/USRFinder.h (added)
> +++ clang-tools-extra/trunk/clang-rename/USRFinder.h Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,39 @@
> +//===--- tools/extra/clang-rename/USRFinder.h - Clang rename tool ---------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief Methods for determining the USR of a symbol at a location in source
> +/// code.
> +///
> +//===----------------------------------------------------------------------===//
> +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H
> +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H
> +
> +#include <string>
> +
> +namespace clang {
> +class ASTContext;
> +class Decl;
> +class SourceLocation;
> +class NamedDecl;
> +
> +namespace rename {
> +
> +// Given an AST context and a point, returns a NamedDecl identifying the symbol
> +// at the point. Returns null if nothing is found at the point.
> +const NamedDecl *getNamedDeclAt(const ASTContext &Context,
> +                                const SourceLocation Point);
> +
> +// Converts a Decl into a USR.
> +std::string getUSRForDecl(const Decl *Decl);
> +
> +}
> +}
> +
> +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H
>
> Added: clang-tools-extra/trunk/clang-rename/USRFindingAction.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/USRFindingAction.cpp?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/USRFindingAction.cpp (added)
> +++ clang-tools-extra/trunk/clang-rename/USRFindingAction.cpp Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,118 @@
> +//===--- tools/extra/clang-rename/USRFindingAction.cpp - Clang rename tool ===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief Provides an action to rename every symbol at a point.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "USRFindingAction.h"
> +#include "USRFinder.h"
> +#include "clang/AST/AST.h"
> +#include "clang/AST/ASTConsumer.h"
> +#include "clang/AST/ASTContext.h"
> +#include "clang/Basic/FileManager.h"
> +#include "clang/Frontend/CompilerInstance.h"
> +#include "clang/Frontend/FrontendAction.h"
> +#include "clang/Lex/Preprocessor.h"
> +#include "clang/Lex/Lexer.h"
> +#include "clang/Tooling/CommonOptionsParser.h"
> +#include "clang/Tooling/Refactoring.h"
> +#include "clang/Tooling/Tooling.h"
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <ctype.h>
> +#include <string>
> +#include <vector>
> +
> +using namespace llvm;
> +
> +namespace clang {
> +namespace rename {
> +
> +// Get the USRs for the constructors of the class.
> +static std::vector<std::string> getAllConstructorUSRs(
> +    const CXXRecordDecl *Decl) {
> +  std::vector<std::string> USRs;
> +
> +  // We need to get the definition of the record (as opposed to any forward
> +  // declarations) in order to find the constructor and destructor.
> +  const auto *RecordDecl = Decl->getDefinition();
> +
> +  // Iterate over all the constructors and add their USRs.
> +  for (const auto &CtorDecl : RecordDecl->ctors())
> +    USRs.push_back(getUSRForDecl(CtorDecl));
> +
> +  // Ignore destructors. GetLocationsOfUSR will find the declaration of and
> +  // explicit calls to a destructor through TagTypeLoc (and it is better for the
> +  // purpose of renaming).
> +  //
> +  // For example, in the following code segment,
> +  //  1  class C {
> +  //  2    ~C();
> +  //  3  };
> +  // At line 3, there is a NamedDecl starting from '~' and a TagTypeLoc starting
> +  // from 'C'.
> +
> +  return USRs;
> +}
> +
> +struct NamedDeclFindingConsumer : public ASTConsumer {
> +  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 = getNamedDeclAt(Context, Point);
> +    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();
> +  }
> +
> +  unsigned SymbolOffset;
> +  std::string *SpellingName;
> +  std::vector<std::string> *USRs;
> +};
> +
> +std::unique_ptr<ASTConsumer>
> +USRFindingAction::newASTConsumer() {
> +  std::unique_ptr<NamedDeclFindingConsumer> Consumer(
> +      new NamedDeclFindingConsumer);
> +  SpellingName = "";
> +  Consumer->SymbolOffset = SymbolOffset;
> +  Consumer->USRs = &USRs;
> +  Consumer->SpellingName = &SpellingName;
> +  return std::move(Consumer);
> +}
> +
> +} // namespace rename
> +} // namespace clang
>
> Added: clang-tools-extra/trunk/clang-rename/USRFindingAction.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/USRFindingAction.h?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/USRFindingAction.h (added)
> +++ clang-tools-extra/trunk/clang-rename/USRFindingAction.h Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,50 @@
> +//===--- tools/extra/clang-rename/USRFindingAction.h - Clang rename tool --===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief Provides an action to find all relevent USRs at a point.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_
> +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_
> +
> +#include "clang/Frontend/FrontendAction.h"
> +
> +namespace clang {
> +class ASTConsumer;
> +class CompilerInstance;
> +class NamedDecl;
> +
> +namespace rename {
> +
> +struct USRFindingAction {
> +  USRFindingAction(unsigned Offset) : SymbolOffset(Offset) {
> +  }
> +  std::unique_ptr<ASTConsumer> newASTConsumer();
> +
> +  // \brief get the spelling of the USR(s) as it would appear in source files.
> +  const std::string &getUSRSpelling() {
> +    return SpellingName;
> +  }
> +
> +  const std::vector<std::string> &getUSRs() {
> +    return USRs;
> +  }
> +
> +private:
> +  unsigned SymbolOffset;
> +  std::string SpellingName;
> +  std::vector<std::string> USRs;
> +};
> +
> +}
> +}
> +
> +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H_
>
> Added: clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp (added)
> +++ clang-tools-extra/trunk/clang-rename/USRLocFinder.cpp Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,103 @@
> +//===--- tools/extra/clang-rename/USRLocFinder.cpp - Clang rename tool ----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief Mehtods for finding all instances of a USR. Our strategy is very
> +/// simple; we just compare the USR at every relevant AST node with the one
> +/// provided.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "USRLocFinder.h"
> +#include "USRFinder.h"
> +#include "clang/AST/ASTContext.h"
> +#include "clang/AST/RecursiveASTVisitor.h"
> +#include "clang/Basic/SourceLocation.h"
> +#include "clang/Index/USRGeneration.h"
> +#include "llvm/ADT/SmallVector.h"
> +
> +using namespace llvm;
> +
> +namespace clang {
> +namespace rename {
> +
> +namespace {
> +// \brief This visitor recursively searches for all instances of a USR in a
> +// translation unit and stores them for later usage.
> +class USRLocFindingASTVisitor
> +    : public clang::RecursiveASTVisitor<USRLocFindingASTVisitor> {
> +public:
> +  explicit USRLocFindingASTVisitor(const std::string USR) : USR(USR) {
> +  }
> +
> +  // Declaration visitors:
> +
> +  bool VisitNamedDecl(const NamedDecl *Decl) {
> +    if (getUSRForDecl(Decl) == USR) {
> +      LocationsFound.push_back(Decl->getLocation());
> +    }
> +    return true;
> +  }
> +
> +  // Expression visitors:
> +
> +  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
> +    const auto *Decl = Expr->getFoundDecl();
> +
> +    checkNestedNameSpecifierLoc(Expr->getQualifierLoc());
> +    if (getUSRForDecl(Decl) == USR) {
> +      LocationsFound.push_back(Expr->getLocation());
> +    }
> +
> +    return true;
> +  }
> +
> +  bool VisitMemberExpr(const MemberExpr *Expr) {
> +    const auto *Decl = Expr->getFoundDecl().getDecl();
> +    if (getUSRForDecl(Decl) == USR) {
> +      LocationsFound.push_back(Expr->getMemberLoc());
> +    }
> +    return true;
> +  }
> +
> +  // 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;
> +  }
> +
> +private:
> +  // Namespace traversal:
> +  void checkNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
> +    while (NameLoc) {
> +      const auto *Decl = NameLoc.getNestedNameSpecifier()->getAsNamespace();
> +      if (Decl && getUSRForDecl(Decl) == USR)
> +        LocationsFound.push_back(NameLoc.getLocalBeginLoc());
> +      NameLoc = NameLoc.getPrefix();
> +    }
> +  }
> +
> +  // All the locations of the USR were found.
> +  const std::string USR;
> +  std::vector<clang::SourceLocation> LocationsFound;
> +};
> +} // namespace
> +
> +std::vector<SourceLocation> getLocationsOfUSR(const std::string USR,
> +                                              Decl *Decl) {
> +  USRLocFindingASTVisitor visitor(USR);
> +
> +  visitor.TraverseDecl(Decl);
> +  return visitor.getLocationsFound();
> +}
> +
> +} // namespace rename
> +} // namespace clang
>
> Added: clang-tools-extra/trunk/clang-rename/USRLocFinder.h
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-rename/USRLocFinder.h?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/clang-rename/USRLocFinder.h (added)
> +++ clang-tools-extra/trunk/clang-rename/USRLocFinder.h Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,35 @@
> +//===--- tools/extra/clang-rename/USRLocFinder.h - Clang rename tool ------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief Provides functionality for finding all instances of a USR in a given
> +/// AST.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H
> +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H
> +
> +#include <string>
> +#include <vector>
> +
> +namespace clang {
> +
> +class Decl;
> +class SourceLocation;
> +
> +namespace rename {
> +
> +// FIXME: make this an AST matcher. Wouldn't that be awesome??? I agree!
> +std::vector<SourceLocation> getLocationsOfUSR(const std::string usr,
> +                                              Decl *decl);
> +}
> +}
> +
> +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H
>
> Modified: clang-tools-extra/trunk/test/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/CMakeLists.txt?rev=215839&r1=215838&r2=215839&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/test/CMakeLists.txt (original)
> +++ clang-tools-extra/trunk/test/CMakeLists.txt Sun Aug 17 13:00:59 2014
> @@ -37,6 +37,7 @@ set(CLANG_TOOLS_TEST_DEPS
>    # Individual tools we test.
>    clang-apply-replacements
>    clang-modernize
> +  clang-rename
>    clang-query
>    clang-tidy
>    modularize
>
> Added: clang-tools-extra/trunk/test/clang-rename/VarTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-rename/VarTest.cpp?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/test/clang-rename/VarTest.cpp (added)
> +++ clang-tools-extra/trunk/test/clang-rename/VarTest.cpp Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,24 @@
> +namespace A {
> +int foo;  // CHECK: int hector;
> +}
> +int foo;  // CHECK: int foo;
> +int bar = foo; // CHECK: bar = foo;
> +int baz = A::foo; // CHECK: baz = A::hector;
> +void fun1() {
> +  struct {
> +    int foo; // CHECK: int foo;
> +  } b = { 100 };
> +  int foo = 100; // CHECK: int foo
> +  baz = foo; // CHECK: baz = foo;
> +  {
> +    extern int foo; // CHECK: int foo;
> +    baz = foo; // CHECK: baz = foo;
> +    foo = A::foo + baz; // CHECK: foo = A::hector + baz;
> +    A::foo = b.foo; // CHECK: A::hector = b.foo;
> +  }
> +  foo = b.foo; // CHECK: foo = b.foo;
> +}
> +// REQUIRES: shell
> +// RUN: cat %s > %t.cpp
> +// RUN: clang-rename -offset=$(grep -FUbo 'foo;' %t.cpp | head -1 | cut -d: -f1) -new-name=hector %t.cpp -i --
> +// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
>
> Modified: clang-tools-extra/trunk/unittests/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/CMakeLists.txt?rev=215839&r1=215838&r2=215839&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/CMakeLists.txt (original)
> +++ clang-tools-extra/trunk/unittests/CMakeLists.txt Sun Aug 17 13:00:59 2014
> @@ -7,5 +7,6 @@ endfunction()
>
>  add_subdirectory(clang-apply-replacements)
>  add_subdirectory(clang-modernize)
> +add_subdirectory(clang-rename)
>  add_subdirectory(clang-query)
>  add_subdirectory(clang-tidy)
>
> Added: clang-tools-extra/trunk/unittests/clang-rename/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-rename/CMakeLists.txt?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/clang-rename/CMakeLists.txt (added)
> +++ clang-tools-extra/trunk/unittests/clang-rename/CMakeLists.txt Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,33 @@
> +set(LLVM_LINK_COMPONENTS
> +  support
> +  )
> +
> +get_filename_component(CLANG_RENAME_SOURCE_DIR
> +  ${CMAKE_CURRENT_SOURCE_DIR}/../../clang-rename REALPATH)
> +include_directories(
> +  ${CLANG_RENAME_SOURCE_DIR}
> +  )
> +
> +add_extra_unittest(ClangRenameTests
> +  USRLocFindingTest.cpp
> +  ${CLANG_RENAME_SOURCE_DIR}/USRFinder.cpp
> +  ${CLANG_RENAME_SOURCE_DIR}/USRFindingAction.cpp
> +  )
> +
> +target_link_libraries(ClangRenameTests
> +  clangAnalysis
> +  clangAST
> +  clangBasic
> +  clangDriver
> +  clangEdit
> +  clangFrontend
> +  clangFrontendTool
> +  clangIndex
> +  clangLex
> +  clangParse
> +  clangRewrite
> +  clangRewriteFrontend
> +  clangSerialization
> +  clangSema
> +  clangTooling
> +  )
> \ No newline at end of file
>
> Added: clang-tools-extra/trunk/unittests/clang-rename/Makefile
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-rename/Makefile?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/clang-rename/Makefile (added)
> +++ clang-tools-extra/trunk/unittests/clang-rename/Makefile Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,24 @@
> +##===- unittests/clang-rename/Makefile ---------------------*- Makefile -*-===##
> +#
> +#                     The LLVM Compiler Infrastructure
> +#
> +# This file is distributed under the University of Illinois Open Source
> +# License. See LICENSE.TXT for details.
> +#
> +##===----------------------------------------------------------------------===##
> +
> +CLANG_LEVEL = ../../../..
> +include $(CLANG_LEVEL)/../../Makefile.config
> +
> +TESTNAME = ClangRenameTests
> +LINK_COMPONENTS := asmparser bitreader support MC MCParser option \
> +                TransformUtils
> +USEDLIBS = clangAnalysis.a clangAST.a clangBasic.a clangDriver.a clangEdit.a \
> +          clangFrontend.a clangFrontendTool.a clangIndex.a clangLex.a \
> +          clangParse.a clangRewrite.a clangRewriteFrontend.a \
> +          clangSerialization.a clangSema.a clangTooling.a
> +
> +include $(CLANG_LEVEL)/Makefile
> +MAKEFILE_UNITTEST_NO_INCLUDE_COMMON := 1
> +CPP.Flags += -I(PROJ_SRC_DIR)/../../clang-rename
> +include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
>
> Added: clang-tools-extra/trunk/unittests/clang-rename/USRLocFindingTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-rename/USRLocFindingTest.cpp?rev=215839&view=auto
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/clang-rename/USRLocFindingTest.cpp (added)
> +++ clang-tools-extra/trunk/unittests/clang-rename/USRLocFindingTest.cpp Sun Aug 17 13:00:59 2014
> @@ -0,0 +1,77 @@
> +#include "USRFindingAction.h"
> +#include "gtest/gtest.h"
> +#include "clang/Tooling/Tooling.h"
> +#include <stdio.h>
> +#include <set>
> +#include <map>
> +#include <vector>
> +
> +namespace clang {
> +namespace rename {
> +namespace test {
> +
> +// Determines if the symbol group invariants hold. To recap, those invariants
> +// are:
> +//  (1) All symbols in the same symbol group share the same USR.
> +//  (2) Two symbols from two different groups do not share the same USR.
> +static void testOffsetGroups(const char *Code,
> +                             const std::vector<std::vector<unsigned>> Groups) {
> +  std::set<std::string> AllUSRs, CurrUSR;
> +
> +  for (const auto &Group : Groups) {
> +    // Groups the invariants do not hold then the value of USR is also invalid,
> +    // but at that point the test has already failed and USR ceases to be
> +    // useful.
> +    std::string USR;
> +    for (const auto &Offset : Group) {
> +      USRFindingAction Action(Offset);
> +      auto Factory = tooling::newFrontendActionFactory(&Action);
> +      EXPECT_TRUE(tooling::runToolOnCode(Factory->create(), Code));
> +      const auto &USRs = Action.getUSRs();
> +      EXPECT_EQ(1u, USRs.size());
> +      USR = USRs[0];
> +      CurrUSR.insert(USR);
> +    }
> +    EXPECT_EQ(1u, CurrUSR.size());
> +    CurrUSR.clear();
> +    AllUSRs.insert(USR);
> +  }
> +
> +  EXPECT_EQ(Groups.size(), AllUSRs.size());
> +}
> +
> +
> +TEST(USRLocFinding, FindsVarUSR) {
> +  const char VarTest[] = "\n\
> +namespace A {\n\
> +int foo;\n\
> +}\n\
> +int foo;\n\
> +int bar = foo;\n\
> +int baz = A::foo;\n\
> +void fun1() {\n\
> +  struct {\n\
> +    int foo;\n\
> +  } b = { 100 };\n\
> +  int foo = 100;\n\
> +  baz = foo;\n\
> +  {\n\
> +    extern int foo;\n\
> +    baz = foo;\n\
> +    foo = A::foo + baz;\n\
> +    A::foo = b.foo;\n\
> +  }\n\
> + foo = b.foo;\n\
> +}\n";
> +  std::vector<std::vector<unsigned>> VarTestOffsets = {
> +    { 19, 63, 205, 223 },
> +    { 30, 45, 172, 187 },
> +    { 129, 148, 242 },
> +  };
> +
> +  testOffsetGroups(VarTest, VarTestOffsets);
> +}
> +
> +}
> +}
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list