kadircet updated this revision to Diff 232825.
kadircet added a comment.

- Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71188/new/

https://reviews.llvm.org/D71188

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -1941,6 +1941,24 @@
           "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
           "void foo(int x, int y , int , int (*foo)(int) ) {}",
       },
+      // Ctor initializers.
+      {
+          R"cpp(
+              class Foo {
+                int y = 2;
+                F^oo(int z) __attribute__((weak)) : bar(2){}
+                int bar;
+                int z = 2;
+              };)cpp",
+          R"cpp(
+              class Foo {
+                int y = 2;
+                Foo(int z) __attribute__((weak)) ;
+                int bar;
+                int z = 2;
+              };)cpp",
+          "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n",
+      },
   };
   for (const auto &Case : Cases) {
     SCOPED_TRACE(Case.Test);
Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
===================================================================
--- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/ASTTypeTraits.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Stmt.h"
 #include "clang/Basic/SourceLocation.h"
@@ -141,6 +142,7 @@
 // Contains function signature, except defaulted parameter arguments, body and
 // template parameters if applicable. No need to qualify parameters, as they are
 // looked up in the context containing the function/method.
+// FIXME: Drop attributes in function signature.
 llvm::Expected<std::string>
 getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace,
                       const syntax::TokenBuffer &TokBuf) {
@@ -238,6 +240,46 @@
   return InsertionPoint{Region.EnclosingNamespace, *Offset};
 }
 
+// Returns the range that should be deleted from declaration, which always
+// contains function body. In addition to that it might contain constructor
+// initializers.
+SourceRange getDeletionRange(const FunctionDecl *FD,
+                             const syntax::TokenBuffer &TokBuf) {
+  auto DeletionRange = FD->getBody()->getSourceRange();
+  if (auto *CD = llvm::dyn_cast<CXXConstructorDecl>(FD)) {
+    const auto &SM = TokBuf.sourceManager();
+    // AST doesn't contain the location for ":" in ctor initializers. Therefore
+    // we find it by finding the first ":" before the first ctor initializer.
+    SourceLocation InitStart;
+    // Find the first initializer.
+    for (const auto *CInit : CD->inits()) {
+      // We don't care about in-class initializers.
+      if (CInit->isInClassMemberInitializer())
+        continue;
+      if (InitStart.isInvalid() ||
+          SM.isBeforeInTranslationUnit(CInit->getSourceLocation(), InitStart))
+        InitStart = CInit->getSourceLocation();
+    }
+    if (InitStart.isValid()) {
+      auto Toks = TokBuf.expandedTokens(CD->getSourceRange());
+      // Drop any tokens after the initializer.
+      Toks = Toks.take_while([&TokBuf, &InitStart](const syntax::Token &Tok) {
+        return TokBuf.sourceManager().isBeforeInTranslationUnit(Tok.location(),
+                                                                InitStart);
+      });
+      // Look for the first colon.
+      for (auto &Tok : llvm::reverse(Toks)) {
+        if (Tok.kind() == tok::colon) {
+          InitStart = Tok.location();
+          break;
+        }
+      }
+      DeletionRange.setBegin(InitStart);
+    }
+  }
+  return DeletionRange;
+}
+
 /// Moves definition of a function/method to an appropriate implementation file.
 ///
 /// Before:
@@ -338,7 +380,8 @@
     const tooling::Replacement DeleteFuncBody(
         Sel.AST.getSourceManager(),
         CharSourceRange::getTokenRange(*toHalfOpenFileRange(
-            SM, Sel.AST.getLangOpts(), Source->getBody()->getSourceRange())),
+            SM, Sel.AST.getLangOpts(),
+            getDeletionRange(Source, Sel.AST.getTokens()))),
         ";");
     auto HeaderFE = Effect::fileEdit(SM, SM.getMainFileID(),
                                      tooling::Replacements(DeleteFuncBody));
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to