[clang-rename] revert r215839

The commit broke public build bots for more than 24 hours.

(view as text)
******************** TEST 'Clang Tools :: clang-rename/VarTest.cpp' FAILED ********************
Script:
--
cat /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-nobootstrap-RAincremental/clang.src/tools/extra/test/clang-rename/VarTest.cpp > /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-nobootstrap-RAincremental/clang-build/tools/clang/tools/extra/test/clang-rename/Output/VarTest.cpp.tmp.cpp
clang-rename -offset=$(grep -FUbo 'foo;' /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-nobootstrap-RAincremental/clang-build/tools/clang/tools/extra/test/clang-rename/Output/VarTest.cpp.tmp.cpp | head -1 | cut -d: -f1) -new-name=hector /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-nobootstrap-RAincremental/clang-build/tools/clang/tools/extra/test/clang-rename/Output/VarTest.cpp.tmp.cpp -i --
sed 's,//.*,,' /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-nobootstrap-RAincremental/clang-build/tools/clang/tools/extra/test/clang-rename/Output/VarTest.cpp.tmp.cpp | FileCheck /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-nobootstrap-RAincremental/clang.src/tools/extra/test/clang-rename/VarTest.cpp
--
Exit Code: 1

Command Output (stderr):
--
clang-rename: could not find symbol at /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin11-nobootstrap-RAincremental/clang-build/tools/clang/tools/extra/test/clang-rename/Output/VarTest.cpp.tmp.cpp:2:1 (offset 14).

llvm-svn: 215947
This commit is contained in:
Gerolf Hoflehner 2014-08-18 23:03:30 +00:00
parent f69cba649e
commit 62bf7e83cb
19 changed files with 2 additions and 1005 deletions

View File

@ -1,6 +1,5 @@
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)

View File

@ -13,8 +13,8 @@ include $(CLANG_LEVEL)/../../Makefile.config
PARALLEL_DIRS := remove-cstr-calls tool-template modularize \
module-map-checker pp-trace
DIRS := clang-apply-replacements clang-modernize clang-rename clang-tidy \
clang-query unittests
DIRS := clang-apply-replacements clang-modernize clang-tidy clang-query \
unittests
include $(CLANG_LEVEL)/Makefile

View File

@ -1,20 +0,0 @@
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
clangAST
clangBasic
clangFrontend
clangIndex
clangRewrite
clangTooling
)
install(TARGETS clang-rename RUNTIME DESTINATION bin)

View File

@ -1,151 +0,0 @@
//===--- 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);
}

View File

@ -1,20 +0,0 @@
##===- 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
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a \
clangTooling.a clangParse.a clangSema.a clangIndex.a \
clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
clangStaticAnalyzerCore.a clangAnalysis.a clangRewriteFrontend.a \
clangRewrite.a clangEdit.a clangAST.a clangLex.a clangBasic.a
include $(CLANG_LEVEL)/Makefile

View File

@ -1,90 +0,0 @@
//===--- 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);
}
}
}

View File

@ -1,47 +0,0 @@
//===--- 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_

View File

@ -1,162 +0,0 @@
//===--- 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

View File

@ -1,39 +0,0 @@
//===--- 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

View File

@ -1,118 +0,0 @@
//===--- 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

View File

@ -1,50 +0,0 @@
//===--- 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_

View File

@ -1,103 +0,0 @@
//===--- 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

View File

@ -1,35 +0,0 @@
//===--- 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

View File

@ -37,7 +37,6 @@ set(CLANG_TOOLS_TEST_DEPS
# Individual tools we test.
clang-apply-replacements
clang-modernize
clang-rename
clang-query
clang-tidy
modularize

View File

@ -1,24 +0,0 @@
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

View File

@ -7,6 +7,5 @@ endfunction()
add_subdirectory(clang-apply-replacements)
add_subdirectory(clang-modernize)
add_subdirectory(clang-rename)
add_subdirectory(clang-query)
add_subdirectory(clang-tidy)

View File

@ -1,33 +0,0 @@
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
)

View File

@ -1,24 +0,0 @@
##===- 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

View File

@ -1,84 +0,0 @@
#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(3);
VarTestOffsets[0].push_back(19);
VarTestOffsets[0].push_back(63);
VarTestOffsets[0].push_back(205);
VarTestOffsets[0].push_back(223);
VarTestOffsets[1].push_back(30);
VarTestOffsets[1].push_back(45);
VarTestOffsets[1].push_back(172);
VarTestOffsets[1].push_back(187);
VarTestOffsets[2].push_back(129);
VarTestOffsets[2].push_back(148);
VarTestOffsets[2].push_back(242);
testOffsetGroups(VarTest, VarTestOffsets);
}
}
}
}