Merge remote-tracking branch 'origin/swift-4.1-branch' into stable
diff --git a/lib/Tooling/Refactor/ExtractRepeatedExpressionIntoVariable.cpp b/lib/Tooling/Refactor/ExtractRepeatedExpressionIntoVariable.cpp
index 7e796b6..fcdb9e6 100644
--- a/lib/Tooling/Refactor/ExtractRepeatedExpressionIntoVariable.cpp
+++ b/lib/Tooling/Refactor/ExtractRepeatedExpressionIntoVariable.cpp
@@ -244,7 +244,8 @@
 ExtractRepeatedExpressionIntoVariableOperation::perform(
     ASTContext &Context, const Preprocessor &ThePreprocessor,
     const RefactoringOptionSet &Options, unsigned SelectedCandidateIndex) {
-  std::vector<RefactoringReplacement> Replacements;
+  RefactoringResult Result(std::vector<RefactoringReplacement>{});
+  std::vector<RefactoringReplacement> &Replacements = Result.Replacements;
 
   const SourceManager &SM = Context.getSourceManager();
   SourceLocation InsertionLoc =
@@ -255,6 +256,10 @@
         "no appropriate insertion location found");
 
   StringRef Name = nameForExtractedVariable(E);
+  Result.AssociatedSymbols.push_back(
+      llvm::make_unique<RefactoringResultAssociatedSymbol>(SymbolName(Name)));
+  RefactoringResultAssociatedSymbol *CreatedSymbol =
+      Result.AssociatedSymbols.back().get();
 
   // Create the variable that will hold the value of the duplicate expression.
   std::string VariableDeclarationString;
@@ -265,21 +270,29 @@
   PP.SuppressLifetimeQualifiers = true;
   PP.SuppressUnwrittenScope = true;
   T.print(OS, PP, /*PlaceHolder*/ Name);
+  // FIXME: We should hook into the TypePrinter when moving over to llvm.org
+  // instead and get the offset from it.
+  unsigned NameOffset = StringRef(OS.str()).find(Name);
   OS << " = ";
   PrintingPolicy ExprPP = Context.getPrintingPolicy();
   ExprPP.SuppressStrongLifetime = true;
   ExprPP.SuppressImplicitBase = true;
   E->printPretty(OS, /*Helper=*/nullptr, ExprPP);
   OS << ";\n";
-  Replacements.emplace_back(SourceRange(InsertionLoc, InsertionLoc), OS.str());
+  Replacements.push_back(RefactoringReplacement(
+      SourceRange(InsertionLoc, InsertionLoc), OS.str(), CreatedSymbol,
+      RefactoringReplacement::AssociatedSymbolLocation(
+          llvm::makeArrayRef(NameOffset), /*IsDeclaration=*/true)));
 
   // Replace the duplicates with a reference to the variable.
-  for (const Expr *E : DuplicateExpressions)
-    Replacements.emplace_back(
+  for (const Expr *E : DuplicateExpressions) {
+    Replacements.push_back(RefactoringReplacement(
         SourceRange(SM.getSpellingLoc(E->getLocStart()),
                     getPreciseTokenLocEnd(SM.getSpellingLoc(E->getLocEnd()), SM,
                                           Context.getLangOpts())),
-        Name);
+        Name, CreatedSymbol,
+        /*NameOffset=*/llvm::makeArrayRef(unsigned(0))));
+  }
 
-  return std::move(Replacements);
+  return std::move(Result);
 }
diff --git a/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.cpp b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.cpp
index f5ddc8a..09cfc7b 100644
--- a/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.cpp
+++ b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.cpp
@@ -45,12 +45,12 @@
     ref.object(x).constMethod();
   ref.object(x).method();
 }
-// CHECK3: "AClass &object = ref.object(x);\n" [[@LINE-4]]:3 -> [[@LINE-4]]:3
-// CHECK3-NEXT: "object" [[@LINE-4]]:5 -> [[@LINE-4]]:18
-// CHECK3-NEXT: "object" [[@LINE-4]]:3 -> [[@LINE-4]]:16
+// CHECK3: "AClass &object = ref.object(x);\n" [[@LINE-4]]:3 -> [[@LINE-4]]:3 [Symbol extracted-decl 0 1:9 -> 1:15]
+// CHECK3-NEXT: "object" [[@LINE-4]]:5 -> [[@LINE-4]]:18 [Symbol extracted-decl-ref 0 1:1 -> 1:7]
+// CHECK3-NEXT: "object" [[@LINE-4]]:3 -> [[@LINE-4]]:16 [Symbol extracted-decl-ref 0 1:1 -> 1:7]
 
-// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:45:5 %s | FileCheck --check-prefix=CHECK3 %s
-// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:46:3 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:45:5 -emit-associated %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:46:3 -emit-associated %s | FileCheck --check-prefix=CHECK3 %s
 
 void takesClass4(AWrapper &ref) {
   int x = 0;