Hi klimek,

For variable declarations initialized with new expressions, use 'auto'
for the type specifier.
- Some slight refactoring.
- Added a new test case.

http://llvm-reviews.chandlerc.com/D393

Files:
  cpp11-migrate/UseAuto/UseAuto.cpp
  cpp11-migrate/UseAuto/UseAutoActions.cpp
  cpp11-migrate/UseAuto/UseAutoActions.h
  cpp11-migrate/UseAuto/UseAutoMatchers.cpp
  cpp11-migrate/UseAuto/UseAutoMatchers.h
  test/cpp11-migrate/UseAuto/new.cpp
Index: cpp11-migrate/UseAuto/UseAuto.cpp
===================================================================
--- cpp11-migrate/UseAuto/UseAuto.cpp
+++ cpp11-migrate/UseAuto/UseAuto.cpp
@@ -36,9 +36,13 @@
   unsigned AcceptedChanges = 0;
 
   MatchFinder Finder;
-  UseAutoFixer Fixer(UseAutoTool.getReplacements(), AcceptedChanges, MaxRisk);
+  IteratorReplacer ReplaceIterators(UseAutoTool.getReplacements(),
+                                    AcceptedChanges, MaxRisk);
+  NewReplacer ReplaceNew(UseAutoTool.getReplacements(), AcceptedChanges,
+                         MaxRisk);
 
-  Finder.addMatcher(makeIteratorMatcher(), &Fixer);
+  Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators);
+  Finder.addMatcher(makeDeclWithNewMatcher(), &ReplaceNew);
 
   if (int result = UseAutoTool.run(newFrontendActionFactory(&Finder))) {
     llvm::errs() << "Error encountered during translation.\n";
Index: cpp11-migrate/UseAuto/UseAutoActions.cpp
===================================================================
--- cpp11-migrate/UseAuto/UseAutoActions.cpp
+++ cpp11-migrate/UseAuto/UseAutoActions.cpp
@@ -8,7 +8,8 @@
 //===----------------------------------------------------------------------===//
 ///
 ///  \file
-///  \brief This file contains the implementation of the UseAutoFixer class.
+///  \brief This file contains the implementation of callbacks for the UseAuto
+///  transform.
 ///
 //===----------------------------------------------------------------------===//
 #include "UseAutoActions.h"
@@ -18,8 +19,8 @@
 using namespace clang::tooling;
 using namespace clang;
 
-void UseAutoFixer::run(const MatchFinder::MatchResult &Result) {
-  const VarDecl *D = Result.Nodes.getNodeAs<VarDecl>(DeclNodeId);
+void IteratorReplacer::run(const MatchFinder::MatchResult &Result) {
+  const VarDecl *D = Result.Nodes.getNodeAs<VarDecl>(IteratorDeclId);
 
   assert(D && "Bad Callback. No node provided");
 
@@ -55,3 +56,28 @@
     ++AcceptedChanges;
   }
 }
+
+void NewReplacer::run(const MatchFinder::MatchResult &Result) {
+  const VarDecl *D = Result.Nodes.getNodeAs<VarDecl>(DeclWithNewId);
+
+  assert(D && "Bad Callback. No node provided");
+
+  SourceManager &SM = *Result.SourceManager;
+  if (!SM.isFromMainFile(D->getLocStart())) {
+    return;
+  }
+
+  // Only use auto if the type of the VarDecl is exactly the same as the new
+  // operator. This should always be true as the matcher is looking for
+  // VarDecls with an initializer that is a CXXNewExpr. If there's any sort of
+  // conversion involved, some other AST node will be the initializer.
+  if (D->getType().getCanonicalType() ==
+      D->getInit()->getType().getCanonicalType()) {
+    TypeLoc TL = D->getTypeSourceInfo()->getTypeLoc();
+    CharSourceRange Range(TL.getSourceRange(), true);
+    // Space after 'auto' to handle styles where the pointer indicator goes
+    // next to the variable and not the type specifier.
+    Replace.insert(tooling::Replacement(SM, Range, "auto "));
+    ++AcceptedChanges;
+  }
+}
Index: cpp11-migrate/UseAuto/UseAutoActions.h
===================================================================
--- cpp11-migrate/UseAuto/UseAutoActions.h
+++ cpp11-migrate/UseAuto/UseAutoActions.h
@@ -8,8 +8,8 @@
 //===----------------------------------------------------------------------===//
 ///
 ///  \file
-///  \brief This file contains the declaration of the UseAutoFixer class which
-///  is used as an ASTMatcher callback.
+///  \brief This file contains the declarations for callbacks used by the
+///  UseAuto transform.
 ///
 //===----------------------------------------------------------------------===//
 #ifndef LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_USE_AUTO_ACTIONS_H
@@ -20,15 +20,35 @@
 #include "clang/Tooling/Refactoring.h"
 
 /// \brief The callback to be used for use-auto AST matchers.
-class UseAutoFixer : public clang::ast_matchers::MatchFinder::MatchCallback {
+class IteratorReplacer
+    : public clang::ast_matchers::MatchFinder::MatchCallback {
 public:
-  UseAutoFixer(clang::tooling::Replacements &Replace, unsigned &AcceptedChanges,
-               RiskLevel)
+  IteratorReplacer(clang::tooling::Replacements &Replace,
+                   unsigned &AcceptedChanges, RiskLevel)
       : Replace(Replace), AcceptedChanges(AcceptedChanges) {
   }
 
   /// \brief Entry point to the callback called when matches are made.
-  virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result);
+  virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
+      LLVM_OVERRIDE;
+
+private:
+  clang::tooling::Replacements &Replace;
+  unsigned &AcceptedChanges;
+};
+
+/// \brief The callback used when replacing type specifiers of variable
+/// declarations initialized by a C++ new expression.
+class NewReplacer : public clang::ast_matchers::MatchFinder::MatchCallback {
+public:
+  NewReplacer(clang::tooling::Replacements &Replace, unsigned &AcceptedChanges,
+              RiskLevel)
+      : Replace(Replace), AcceptedChanges(AcceptedChanges) {
+  }
+
+  /// \brief Entry point to the callback called when matches are made.
+  virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result)
+      LLVM_OVERRIDE;
 
 private:
   clang::tooling::Replacements &Replace;
Index: cpp11-migrate/UseAuto/UseAutoMatchers.cpp
===================================================================
--- cpp11-migrate/UseAuto/UseAutoMatchers.cpp
+++ cpp11-migrate/UseAuto/UseAutoMatchers.cpp
@@ -20,7 +20,8 @@
 using namespace clang::ast_matchers;
 using namespace clang;
 
-const char *DeclNodeId = "decl";
+const char *IteratorDeclId = "iterator_decl";
+const char *DeclWithNewId = "decl_new";
 
 namespace clang {
 namespace ast_matchers {
@@ -74,7 +75,7 @@
 } // namespace ast_matchers
 } // namespace clang
 
-DeclarationMatcher makeIteratorMatcher() {
+DeclarationMatcher makeIteratorDeclMatcher() {
   return varDecl(allOf(hasWrittenNonListInitializer(),
                        hasType(recordDecl(anyOf(
                            isDerivedFrom("std::iterator"),
@@ -84,5 +85,9 @@
                                  has(namedDecl(hasName("reference"))),
                                  has(namedDecl(hasName("pointer"))))))),
                        // Skip type-specifiers that are already 'auto'.
-                       unless(hasType(autoType())))).bind(DeclNodeId);
+                       unless(hasType(autoType())))).bind(IteratorDeclId);
+}
+
+DeclarationMatcher makeDeclWithNewMatcher() {
+  return varDecl(hasInitializer(newExpr())).bind(DeclWithNewId);
 }
Index: cpp11-migrate/UseAuto/UseAutoMatchers.h
===================================================================
--- cpp11-migrate/UseAuto/UseAutoMatchers.h
+++ cpp11-migrate/UseAuto/UseAutoMatchers.h
@@ -17,10 +17,15 @@
 
 #include "clang/ASTMatchers/ASTMatchers.h"
 
-extern const char *DeclNodeId;
+extern const char *IteratorDeclId;
+extern const char *DeclWithNewId;
 
 /// \brief Create a matcher that matches declarations where the type is a
 /// subclass of std::iterator or has standard iterator traits.
-clang::ast_matchers::DeclarationMatcher makeIteratorMatcher();
+clang::ast_matchers::DeclarationMatcher makeIteratorDeclMatcher();
+
+/// \brief Create a matcher that matches variable declarations that are
+/// initialized by a C++ new expression.
+clang::ast_matchers::DeclarationMatcher makeDeclWithNewMatcher();
 
 #endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_USE_AUTO_MATCHERS_H
Index: test/cpp11-migrate/UseAuto/new.cpp
===================================================================
--- /dev/null
+++ test/cpp11-migrate/UseAuto/new.cpp
@@ -0,0 +1,20 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -use-auto %t.cpp --
+// RUN: FileCheck -input-file=%t.cpp %s
+
+class MyType {
+};
+
+class MyDerivedType : public MyType {
+};
+
+int main(int argc, char **argv) {
+  MyType *a = new MyType();
+  // CHECK: auto a = new MyType();
+
+  MyType *b = new MyDerivedType();
+  // CHECK: MyType *b = new MyDerivedType();
+
+  void *c = new MyType();
+  // CHECK: void *c = new MyType();
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to