summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Tooling/Refactoring/Extract.cpp9
-rw-r--r--clang/test/Refactor/Extract/FromMethodToFunction.cpp42
2 files changed, 49 insertions, 2 deletions
diff --git a/clang/lib/Tooling/Refactoring/Extract.cpp b/clang/lib/Tooling/Refactoring/Extract.cpp
index e81bb3ffe9b..3f5a839318b 100644
--- a/clang/lib/Tooling/Refactoring/Extract.cpp
+++ b/clang/lib/Tooling/Refactoring/Extract.cpp
@@ -15,6 +15,7 @@
#include "clang/Tooling/Refactoring/Extract/Extract.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/Rewrite/Core/Rewriter.h"
@@ -44,8 +45,12 @@ bool isSimpleExpression(const Expr *E) {
}
SourceLocation computeFunctionExtractionLocation(const Decl *D) {
- // FIXME (Alex L): Method -> function extraction should place function before
- // C++ record if the method is defined inside the record.
+ if (isa<CXXMethodDecl>(D)) {
+ // Code from method that is defined in class body should be extracted to a
+ // function defined just before the class.
+ while (const auto *RD = dyn_cast<CXXRecordDecl>(D->getLexicalDeclContext()))
+ D = RD;
+ }
return D->getLocStart();
}
diff --git a/clang/test/Refactor/Extract/FromMethodToFunction.cpp b/clang/test/Refactor/Extract/FromMethodToFunction.cpp
new file mode 100644
index 00000000000..86bec16edfd
--- /dev/null
+++ b/clang/test/Refactor/Extract/FromMethodToFunction.cpp
@@ -0,0 +1,42 @@
+// RUN: clang-refactor extract -selection=test:%s %s -- -std=c++11 2>&1 | grep -v CHECK | FileCheck --check-prefixes=CHECK,CHECK-INNER %s
+// RUN: clang-refactor extract -selection=test:%s %s -- -std=c++11 -DMULTIPLE 2>&1 | grep -v CHECK | FileCheck --check-prefixes=CHECK,CHECK-OUTER %s
+
+#ifdef MULTIPLE
+class OuterClass {
+#define PREFIX OuterClass ::
+#else
+#define PREFIX
+#endif
+
+class AClass {
+
+ int method(int x) {
+ return /*range inner=->+0:38*/1 + 2 * 2;
+ }
+// CHECK-INNER: 1 'inner' results:
+// CHECK-INNER: static int extracted() {
+// CHECK-INNER-NEXT: return 1 + 2 * 2;{{$}}
+// CHECK-INNER-NEXT: }{{[[:space:]].*}}
+// CHECK-INNER-NEXT: class AClass {
+
+// CHECK-OUTER: 1 'inner' results:
+// CHECK-OUTER: static int extracted() {
+// CHECK-OUTER-NEXT: return 1 + 2 * 2;{{$}}
+// CHECK-OUTER-NEXT: }{{[[:space:]].*}}
+// CHECK-OUTER-NEXT: class OuterClass {
+
+ int otherMethod(int x);
+};
+
+#ifdef MULTIPLE
+};
+#endif
+
+int PREFIX AClass::otherMethod(int x) {
+ return /*range outofline=->+0:46*/2 * 2 - 1;
+}
+// CHECK: 1 'outofline' results:
+// CHECK: static int extracted() {
+// CHECK-NEXT: return 2 * 2 - 1;{{$}}
+// CHECK-NEXT: }{{[[:space:]].*}}
+// CHECK-NEXT: int PREFIX AClass::otherMethod
OpenPOWER on IntegriCloud