[llvm-branch-commits] [cfe-branch] r155648 - in /cfe/branches/tooling/tools: CMakeLists.txt rename/ rename/CMakeLists.txt rename/ClangRename.cpp rename/Makefile
Manuel Klimek
klimek at google.com
Thu Apr 26 11:29:53 PDT 2012
Author: klimek
Date: Thu Apr 26 13:29:52 2012
New Revision: 155648
URL: http://llvm.org/viewvc/llvm-project?rev=155648&view=rev
Log:
Adds a tool that does a rename refactoring; this is a manually tested and unmaintenable spike.
Added:
cfe/branches/tooling/tools/rename/
cfe/branches/tooling/tools/rename/CMakeLists.txt (with props)
cfe/branches/tooling/tools/rename/ClangRename.cpp (with props)
cfe/branches/tooling/tools/rename/Makefile (with props)
Modified:
cfe/branches/tooling/tools/CMakeLists.txt
Modified: cfe/branches/tooling/tools/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/CMakeLists.txt?rev=155648&r1=155647&r2=155648&view=diff
==============================================================================
--- cfe/branches/tooling/tools/CMakeLists.txt (original)
+++ cfe/branches/tooling/tools/CMakeLists.txt Thu Apr 26 13:29:52 2012
@@ -7,3 +7,4 @@
add_subdirectory(clang-check)
add_subdirectory(remove-cstr-calls)
add_subdirectory(fix-llvm-style)
+add_subdirectory(rename)
Added: cfe/branches/tooling/tools/rename/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/rename/CMakeLists.txt?rev=155648&view=auto
==============================================================================
--- cfe/branches/tooling/tools/rename/CMakeLists.txt (added)
+++ cfe/branches/tooling/tools/rename/CMakeLists.txt Thu Apr 26 13:29:52 2012
@@ -0,0 +1,5 @@
+set(LLVM_USED_LIBS clangTooling clangBasic clangAST)
+
+add_clang_executable(clang-rename
+ ClangRename.cpp
+ )
Propchange: cfe/branches/tooling/tools/rename/CMakeLists.txt
------------------------------------------------------------------------------
svn:eol-style = LF
Added: cfe/branches/tooling/tools/rename/ClangRename.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/rename/ClangRename.cpp?rev=155648&view=auto
==============================================================================
--- cfe/branches/tooling/tools/rename/ClangRename.cpp (added)
+++ cfe/branches/tooling/tools/rename/ClangRename.cpp Thu Apr 26 13:29:52 2012
@@ -0,0 +1,522 @@
+//=- tools/fix-llvm-style/FixLLVMStyle.cpp - Automatic LLVM style correction =//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// FIXME: This is an early first draft that needs clean-up.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+
+#include "clang/AST/DeclTemplate.h"
+
+using namespace clang;
+using namespace clang::ast_matchers;
+using namespace llvm;
+using clang::tooling::newFrontendActionFactory;
+using clang::tooling::Replacement;
+using clang::tooling::CompilationDatabase;
+
+template <typename T>
+class TestVisitor : public clang::RecursiveASTVisitor<T> {
+public:
+ FrontendAction *newFrontendAction() { return new TestAction(this); }
+
+ bool shouldVisitTemplateInstantiations() const {
+ return true;
+ }
+
+protected:
+ clang::ASTContext *Context;
+
+private:
+ class FindConsumer : public clang::ASTConsumer {
+ public:
+ FindConsumer(TestVisitor *Visitor) : Visitor(Visitor) {}
+
+ virtual void HandleTranslationUnit(clang::ASTContext &Context) {
+ Visitor->TraverseDecl(Context.getTranslationUnitDecl());
+ }
+
+ private:
+ TestVisitor *Visitor;
+ };
+
+ class TestAction : public clang::ASTFrontendAction {
+ public:
+ TestAction(TestVisitor *Visitor) : Visitor(Visitor) {}
+
+ virtual clang::ASTConsumer* CreateASTConsumer(
+ clang::CompilerInstance& compiler, llvm::StringRef dummy) {
+ Visitor->Context = &compiler.getASTContext();
+ /// TestConsumer will be deleted by the framework calling us.
+ return new FindConsumer(Visitor);
+ }
+
+ private:
+ TestVisitor *Visitor;
+ };
+};
+
+struct Xaver {
+ void rvgl();
+ void c() {
+ rvgl();
+ }
+};
+
+class Yaver : public Xaver {
+ using Xaver::rvgl;
+
+ void d() {
+ rvgl();
+ }
+};
+
+cl::opt<std::string> LocationPath("f", cl::desc("<location-path>"));
+cl::opt<std::string> RenameTo("t", cl::desc("<rename-to>"));
+cl::opt<unsigned> LocationLine("l", cl::desc("<location-line>"));
+cl::opt<unsigned> LocationColumn("c", cl::desc("<location-column>"));
+
+SourceRange getIdentifierRange(Decl* D) {
+ SourceRange TokenRange;
+ if (FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
+ TokenRange = F->getNameInfo().getSourceRange();
+ } else if (VarDecl *V = dyn_cast<VarDecl>(D)) {
+ TokenRange = SourceRange(V->getLocation(), V->getLocation());
+ } else if (UsingDecl *U = dyn_cast<UsingDecl>(D)) {
+ TokenRange = U->getNameInfo().getSourceRange();
+ } else {
+/* llvm::errs() << "Not supported:\n";
+ D->dump();
+ llvm::errs() << "\n";*/
+ return SourceRange();
+ }
+ return TokenRange;
+}
+
+struct ExpandedIdentifierRange {
+ ExpandedIdentifierRange() : Line(0), StartColumn(0), EndColumn(0) {}
+ std::string File;
+ unsigned Line;
+ unsigned StartColumn;
+ unsigned EndColumn;
+};
+
+ExpandedIdentifierRange getExpandedIdentifierRange(SourceLocation L, ASTContext *Context) {
+ SourceLocation S = Context->getSourceManager().getSpellingLoc(L);
+ FileID ID = Context->getSourceManager().getFileID(S);
+ const FileEntry *Entry = Context->getSourceManager().getFileEntryForID(ID);
+ ExpandedIdentifierRange IR;
+ if (Entry == NULL)
+ return IR;
+ IR.Line = Context->getSourceManager().getSpellingLineNumber(S);
+ IR.StartColumn = Context->getSourceManager().getSpellingColumnNumber(S);
+ IR.File = Entry->getName();
+ IR.EndColumn = IR.StartColumn + Lexer::MeasureTokenLength(S, Context->getSourceManager(), LangOptions());
+ return IR;
+}
+
+std::string getDeclarationKey(Decl *DL, ASTContext *Context) {
+ Decl *D = DL->getCanonicalDecl();
+ while (UsingDecl *U = dyn_cast<UsingDecl>(D)) {
+ // FIXME: If there are multiple shadow decls, we need to get that information up and awrn / error.
+ D = (*U->shadow_begin())->getTargetDecl()->getCanonicalDecl();
+ }
+ ExpandedIdentifierRange R = getExpandedIdentifierRange(getIdentifierRange(D).getBegin(), Context);
+ std::string Location;
+ if (R.File.empty())
+ return Location;
+ llvm::raw_string_ostream S(Location);
+ S << R.File << ":" << R.Line << ":" << R.StartColumn;
+ S.flush();
+ return Location;
+}
+
+bool UnderCursor(SourceLocation IR, ASTContext *Context) {
+ ExpandedIdentifierRange R = getExpandedIdentifierRange(IR, Context);
+ if (R.File.empty())
+ return false;
+// llvm::outs() << R.File << ":" << R.Line << ":" << R.StartColumn << "\n";
+ StringRef FileName(R.File);
+ return FileName.endswith(LocationPath) && R.Line == LocationLine && R.StartColumn <= LocationColumn && LocationColumn <= R.EndColumn;
+}
+
+class GetIdentifierAtVisitor : public TestVisitor<GetIdentifierAtVisitor> {
+public:
+// bool TraverseDeclarationNameInfo(DeclarationNameInfo NI) {
+ bool VisitDeclRefExpr(DeclRefExpr *DR) {
+ if (UnderCursor(DR->getLocation(), Context))
+ Key = getDeclarationKey(DR->getDecl(), Context);
+ return true;
+ }
+
+ bool VisitDecl(Decl *D) {
+ if (UnderCursor(getIdentifierRange(D).getBegin(), Context))
+ Key = getDeclarationKey(D, Context);
+ return true;
+ }
+
+ bool VisitMemberExpr(MemberExpr *C) {
+ if (UnderCursor(C->getMemberLoc(), Context))
+ Key = getDeclarationKey(C->getMemberDecl(), Context);
+ return true;
+ }
+
+ std::string Key;
+};
+
+class RenameIdentifierVisitor : public TestVisitor<RenameIdentifierVisitor> {
+public:
+ RenameIdentifierVisitor(std::string Key, tooling::Replacements *Replacements) : Key(Key), Replacements(Replacements) {}
+
+ bool VisitDeclRefExpr(DeclRefExpr *DR) {
+ if (getDeclarationKey(DR->getDecl(), Context) == Key) {
+ llvm::outs() << Key << "\n";
+ Replacement R(Context->getSourceManager(), DR, RenameTo);
+ llvm::outs() << R.getFilePath() << ":" << R.getOffset() << ":" << R.getLength() << "\n";
+ Replacements->insert(R);
+ }
+ return true;
+ }
+
+ bool VisitDecl(Decl *D) {
+ if (getDeclarationKey(D, Context) == Key) {
+ Replacement R(Context->getSourceManager(), CharSourceRange::getTokenRange(SourceRange(D->getLocation())), RenameTo);
+ llvm::outs() << R.getFilePath() << ":" << R.getOffset() << ":" << R.getLength() << "\n";
+ Replacements->insert(R);
+ }
+ return true;
+ }
+
+ bool VisitMemberExpr(MemberExpr *C) {
+ if (getDeclarationKey(C->getMemberDecl(), Context) == Key) {
+ Replacement R(Context->getSourceManager(), CharSourceRange::getTokenRange(SourceRange(C->getMemberLoc())), RenameTo);
+ llvm::outs() << R.getFilePath() << ":" << R.getOffset() << ":" << R.getLength() << "\n";
+ Replacements->insert(R);
+ }
+ return true;
+ }
+
+ std::string Key;
+ tooling::Replacements *Replacements;
+};
+
+cl::opt<std::string> BuildPath(
+ cl::Positional,
+ cl::desc("<build-path>"));
+
+cl::list<std::string> SourcePaths(
+ cl::Positional,
+ cl::desc("<source0> [... <sourceN>]"),
+ cl::OneOrMore);
+
+int main(int argc, char **argv) {
+ cl::ParseCommandLineOptions(argc, argv);
+ std::string ErrorMessage;
+ llvm::OwningPtr<CompilationDatabase> Compilations(
+ CompilationDatabase::loadFromDirectory(BuildPath, ErrorMessage));
+ if (!Compilations)
+ llvm::report_fatal_error(ErrorMessage);
+ tooling::RefactoringTool Tool(*Compilations, SourcePaths);
+ GetIdentifierAtVisitor GetIdentifierVisitor;
+ Tool.run(newFrontendActionFactory(&GetIdentifierVisitor));
+ llvm::outs() << GetIdentifierVisitor.Key << "\n";
+ if (GetIdentifierVisitor.Key.empty()) {
+ llvm::errs() << "Noooooooooooo!!!!!\n";
+ return -1;
+ }
+ RenameIdentifierVisitor Renamer(GetIdentifierVisitor.Key, &Tool.getReplacements());
+ return Tool.run(newFrontendActionFactory(&Renamer));
+}
+
+/*
+// FIXME: Pull out helper methods in here into more fitting places.
+
+template <typename T>
+std::string getFile(const clang::SourceManager& source_manager, const T& node) {
+ clang::SourceLocation start_spelling_location =
+ source_manager.getSpellingLoc(node.getLocStart());
+ if (!start_spelling_location.isValid()) return std::string();
+ clang::FileID file_id = source_manager.getFileID(start_spelling_location);
+ const clang::FileEntry* file_entry =
+ source_manager.getFileEntryForID(file_id);
+ if (file_entry == NULL) return std::string();
+ return file_entry->getName();
+}
+
+// Returns the text that makes up 'node' in the source.
+// Returns an empty string if the text cannot be found.
+static std::string getText(const SourceManager &SourceManager,
+ SourceLocation LocStart, SourceLocation LocEnd) {
+ SourceLocation StartSpellingLocatino =
+ SourceManager.getSpellingLoc(LocStart);
+ SourceLocation EndSpellingLocation =
+ SourceManager.getSpellingLoc(LocEnd);
+ if (!StartSpellingLocatino.isValid() || !EndSpellingLocation.isValid()) {
+ return std::string();
+}
+ bool Invalid = true;
+ const char *Text =
+ SourceManager.getCharacterData(StartSpellingLocatino, &Invalid);
+ if (Invalid) {
+ return std::string();
+ }
+ std::pair<FileID, unsigned> Start =
+ SourceManager.getDecomposedLoc(StartSpellingLocatino);
+ std::pair<FileID, unsigned> End =
+ SourceManager.getDecomposedLoc(Lexer::getLocForEndOfToken(
+ EndSpellingLocation, 0, SourceManager, LangOptions()));
+ if (Start.first != End.first) {
+ // Start and end are in different files.
+ return std::string();
+ }
+ if (End.second < Start.second) {
+ // Shuffling text with macros may cause this.
+ return std::string();
+ }
+ return std::string(Text, End.second - Start.second);
+}
+
+template <typename T>
+static std::string getText(const SourceManager &SourceManager, const T &Node) {
+ return GetText(SourceManager, Node.getLocStart(), Node.getLocEnd());
+}
+
+namespace {
+
+bool hasMethod(const CXXRecordDecl &Decl, StringRef MethodName, ASTContext &Context) {
+ clang::IdentifierInfo& Identifier = Context.Idents.get(MethodName);
+ clang::DeclContext::lookup_const_result Result = Decl.lookup(&Identifier);
+ return Result.first != Result.second;
+}
+
+bool allParentsMatch(SourceManager *SM, ASTContext &Context, const CXXRecordDecl *Decl, StringRef MethodName, llvm::Regex &EditFilesExpression) {
+ if (Decl == NULL)
+ return true;
+ if (!EditFilesExpression.match(getFile(*SM, *Decl)) &&
+ hasMethod(*Decl, MethodName, Context)) {
+ //llvm::outs() << GetFile(*SM, *Decl) << "\n";
+ return false;
+ }
+ typedef clang::CXXRecordDecl::base_class_const_iterator BaseIterator;
+ for (BaseIterator It = Decl->bases_begin(),
+ End = Decl->bases_end(); It != End; ++It) {
+ const clang::Type *TypeNode = It->getType().getTypePtr();
+ clang::CXXRecordDecl *
+ ClassDecl = TypeNode->getAsCXXRecordDecl();
+ if (!allParentsMatch(SM, Context, ClassDecl, MethodName, EditFilesExpression)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+class FixLLVMStyle: public ast_matchers::MatchFinder::MatchCallback {
+ public:
+ FixLLVMStyle(tooling::Replacements *Replace)
+ : Replace(Replace),
+
+ virtual void run(const ast_matchers::MatchFinder::MatchResult &Result) {
+ if (const CallExpr *Call = Result.Nodes.getStmtAs<CallExpr>("call")) {
+ return;
+ }
+ Replacement ReplaceText;
+ std::string Name;
+ std::string OldName;
+ std::string SedCommand;
+ if (const NamedDecl *Declaration =
+ Result.Nodes.getDeclAs<NamedDecl>("declaration")) {
+ if (!EditFilesExpression.match(getFile(*Result.SourceManager, *Declaration)))
+ return;
+ Name = Declaration->getNameAsString();
+ OldName = Name;
+ if (const CXXMethodDecl *Method =
+ llvm::dyn_cast<CXXMethodDecl>(Declaration)) {
+ if (//Method->size_overridden_methods() > 0 &&
+ !allParentsMatch(Result.SourceManager, *Result.Context, Method->getParent(), OldName, EditFilesExpression)) {
+ // llvm::errs() << "NotAllParentsMatch: " << OldName << "\n";
+ return;
+ }
+ }
+ if (isupper(Name[0])) {
+ Name[0] = tolower(Name[0]);
+ if (Name == "new") Name = "create";
+
+ if (const DeclRefExpr *Reference = Result.Nodes.getStmtAs<DeclRefExpr>("ref")) {
+ ReplaceText = Replacement(*Result.SourceManager, Reference, Name);
+ } else if (const Expr *Callee = Result.Nodes.getStmtAs<Expr>("callee")) {
+ if (const MemberExpr *Member = dyn_cast<MemberExpr>(Callee)) {
+ // llvm::errs() << OldName << "\n";
+ assert(Member != NULL);
+// std::string CalleeText = GetText(*Result.SourceManager, *Callee);
+// llvm::outs() << "Callee: " << CalleeText << "\n";
+// std::string ReplacementText =
+// Name + CalleeText.substr(OldName.size(), CalleeText.size() - OldName.size());
+ ReplaceText = Replacement(*Result.SourceManager, CharSourceRange::getTokenRange(SourceRange(Member->getMemberLoc(), Member->getMemberLoc())),
+ Name);
+ } else if (const DeclRefExpr *Ref = dyn_cast<DeclRefExpr>(Callee)) {
+ (void)Ref;
+ // llvm::errs() << "XXX " << GetFile(*Result.SourceManager, *Callee) << "\n";
+ } else {
+ // llvm::errs() << "*** " << GetFile(*Result.SourceManager, *Callee) << "\n";
+ //Callee->dump();
+ }
+ } else {
+ DeclarationNameInfo NameInfo;
+ if (const FunctionDecl *Function = llvm::dyn_cast<FunctionDecl>(Declaration)) {
+ NameInfo = Function->getNameInfo();
+ } else if (const UsingDecl *Using = llvm::dyn_cast<UsingDecl>(Declaration)) {
+ NameInfo = Using->getNameInfo();
+ }
+ ReplaceText = Replacement(*Result.SourceManager, &NameInfo, Name);
+ if (!ReplaceText.isApplicable()) {
+ // llvm::errs() << "Not applicable: " << Name << "\n";
+ }
+ }
+ }
+ }
+ if (EditFilesExpression.match(ReplaceText.getFilePath())) {
+ //llvm::errs() << GetPosition(*Result.Nodes.GetDeclAs<NamedDecl>("declaration"), *Result.SourceManager) << "\n";
+ //llvm::errs
+ llvm::errs() << ReplaceText.getFilePath() << ":" << ReplaceText.getOffset() << ", " << ReplaceText.getLength() << ": s/" << OldName << "/" << Name << "/g;\n";
+ Replace->insert(ReplaceText);
+ } else {
+// llvm::errs() << ReplaceText.GetFilePath() << ":" << ReplaceText.GetOffset() << ", " << ReplaceText.GetLength() << ": s/" << OldName << "/" << Name << "/g;\n";
+ }
+ }
+
+ private:
+ tooling::Replacements *Replace;
+ llvm::Regex EditFilesExpression;
+};
+} // end namespace
+
+const internal::VariadicDynCastAllOfMatcher<clang::Decl, clang::UsingDecl> UsingDeclaration;
+namespace clang { namespace ast_matchers {
+AST_MATCHER_P(clang::UsingDecl, HasAnyUsingShadowDeclaration,
+ internal::Matcher<clang::UsingShadowDecl>, InnerMatcher) {
+ for (clang::UsingDecl::shadow_iterator I = Node.shadow_begin();
+ I != Node.shadow_end(); ++I) {
+ if (InnerMatcher.matches(**I, Finder, Builder)) {
+ return true;
+ }
+ }
+ return false;
+}
+AST_MATCHER_P(clang::UsingShadowDecl, HasTargetDeclaration,
+ internal::Matcher<clang::NamedDecl>, InnerMatcher) {
+ return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder);
+}
+AST_MATCHER_P(clang::QualType, HasClassDeclaration,
+ internal::Matcher<clang::CXXRecordDecl>, InnerMatcher) {
+ if (const clang::CXXRecordDecl *Decl = Node->getAsCXXRecordDecl()) {
+ return InnerMatcher.matches(*Decl, Finder, Builder);
+ }
+ if (const clang::TemplateSpecializationType *T = Node->getAs<clang::TemplateSpecializationType>()) {
+ if (const clang::NamedDecl *N = T->getTemplateName().getAsTemplateDecl()->getTemplatedDecl()) {
+ if (const clang::CXXRecordDecl *Decl = dyn_cast<CXXRecordDecl>(N)) {
+ return InnerMatcher.matches(*Decl, Finder, Builder);
+ }
+ }
+ }
+ return false;
+}
+AST_MATCHER_P(clang::FunctionDecl, HasReturnType,
+ internal::Matcher<clang::QualType>, InnerMatcher) {
+ llvm::errs() << Node.getNameAsString() << "\n";
+ Node.getResultType().dump();
+ llvm::errs() << "\n";
+ const clang::TemplateSpecializationType* T = Node.getResultType()->getAs<clang::TemplateSpecializationType>();
+ if (T != NULL) {
+ const NamedDecl *N = T->getTemplateName().getAsTemplateDecl()->getTemplatedDecl();
+
+ if (N != NULL) {
+ llvm::errs() << dyn_cast<CXXRecordDecl>(N) << "\n";
+ }
+
+ }
+ return InnerMatcher.matches(Node.getResultType(), Finder, Builder);
+}
+AST_MATCHER_P(clang::NamedDecl, HasName2, std::string, name) {
+ assert(!name.empty());
+ const std::string full_name_string = "::" + Node.getQualifiedNameAsString();
+ const llvm::StringRef full_name = full_name_string;
+ llvm::errs() << full_name << "\n";
+ const llvm::StringRef pattern = name;
+ if (pattern.startswith("::")) {
+ return full_name == pattern;
+ } else {
+ return full_name.endswith(("::" + pattern).str());
+ }
+}
+} }
+
+
+cl::opt<std::string> BuildPath(
+ cl::Positional,
+ cl::desc("<build-path>"));
+
+cl::list<std::string> SourcePaths(
+ cl::Positional,
+ cl::desc("<source0> [... <sourceN>]"),
+ cl::OneOrMore);
+
+int main(int argc, char **argv) {
+ cl::ParseCommandLineOptions(argc, argv);
+ std::string ErrorMessage;
+ llvm::OwningPtr<CompilationDatabase> Compilations(
+ CompilationDatabase::loadFromDirectory(BuildPath, ErrorMessage));
+ if (!Compilations)
+ llvm::report_fatal_error(ErrorMessage);
+ tooling::RefactoringTool Tool(*Compilations, SourcePaths);
+ ast_matchers::MatchFinder Finder;
+
+ DeclarationMatcher FunctionMatch = Function(Not(HasReturnType(HasClassDeclaration(
+ AnyOf(HasName2("internal::Matcher"),
+ HasName("internal::PolymorphicMatcherWithParam0"),
+ HasName("internal::PolymorphicMatcherWithParam1"),
+ HasName("internal::PolymorphicMatcherWithParam2")
+ )))));
+
+ FixLLVMStyle Callback(&Tool.getReplacements());
+ Finder.addMatcher(StatementMatcher(AnyOf(
+ StatementMatcher(Id("ref", DeclarationReference(To(Id("declaration", FunctionMatch))))),
+ Call(Callee(Id("declaration", FunctionMatch)),
+ Callee(Id("callee", Expression()))))),
+ &Callback);
+
+ Finder.addMatcher(
+ DeclarationMatcher(AnyOf(
+ Id("declaration", UsingDeclaration(HasAnyUsingShadowDeclaration(HasTargetDeclaration(FunctionMatch)))),
+ AllOf(
+ Id("declaration", FunctionMatch),
+ Not(Constructor())))
+ ),
+ &Callback);
+ return Tool.run(newFrontendActionFactory(&Finder));
+}
+*/
Propchange: cfe/branches/tooling/tools/rename/ClangRename.cpp
------------------------------------------------------------------------------
svn:eol-style = LF
Added: cfe/branches/tooling/tools/rename/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/rename/Makefile?rev=155648&view=auto
==============================================================================
--- cfe/branches/tooling/tools/rename/Makefile (added)
+++ cfe/branches/tooling/tools/rename/Makefile Thu Apr 26 13:29:52 2012
@@ -0,0 +1,23 @@
+##===- tools/remove-cstr-calls/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
+NO_INSTALL = 1
+
+# No plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+LINK_COMPONENTS := support mc
+USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
+ clangRewrite.a clangParse.a clangSema.a clangAnalysis.a \
+ clangAST.a clangASTMatchers.a clangLex.a clangBasic.a
+
+include $(CLANG_LEVEL)/Makefile
Propchange: cfe/branches/tooling/tools/rename/Makefile
------------------------------------------------------------------------------
svn:eol-style = LF
More information about the llvm-branch-commits
mailing list