Automatic Reference Counting.

Language-design credit goes to a lot of people, but I particularly want
to single out Blaine Garst and Patrick Beard for their contributions.

Compiler implementation credit goes to Argyrios, Doug, Fariborz, and myself,
in no particular order.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133103 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp
index 51fe379..92f5160 100644
--- a/lib/Rewrite/Rewriter.cpp
+++ b/lib/Rewrite/Rewriter.cpp
@@ -231,10 +231,44 @@
 /// InsertText - Insert the specified string at the specified location in the
 /// original buffer.
 bool Rewriter::InsertText(SourceLocation Loc, llvm::StringRef Str,
-                          bool InsertAfter) {
+                          bool InsertAfter, bool indentNewLines) {
+  using llvm::StringRef;
+
   if (!isRewritable(Loc)) return true;
   FileID FID;
   unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
+
+  llvm::SmallString<128> indentedStr;
+  if (indentNewLines && Str.find('\n') != StringRef::npos) {
+    StringRef MB = SourceMgr->getBufferData(FID);
+
+    unsigned lineNo = SourceMgr->getLineNumber(FID, StartOffs) - 1;
+    const SrcMgr::ContentCache *
+        Content = SourceMgr->getSLocEntry(FID).getFile().getContentCache();
+    unsigned lineOffs = Content->SourceLineCache[lineNo];
+
+    // Find the whitespace at the start of the line.
+    StringRef indentSpace;
+    {
+      unsigned i = lineOffs;
+      while (isWhitespace(MB[i]))
+        ++i;
+      indentSpace = MB.substr(lineOffs, i-lineOffs);
+    }
+
+    llvm::SmallVector<StringRef, 4> lines;
+    Str.split(lines, "\n");
+
+    for (unsigned i = 0, e = lines.size(); i != e; ++i) {
+      indentedStr += lines[i];
+      if (i < e-1) {
+        indentedStr += '\n';
+        indentedStr += indentSpace;
+      }
+    }
+    Str = indentedStr.str();
+  }
+
   getEditBuffer(FID).InsertText(StartOffs, Str, InsertAfter);
   return false;
 }
@@ -317,6 +351,7 @@
                                    SourceLocation parentIndent) {
   using llvm::StringRef;
 
+  if (range.isInvalid()) return true;
   if (!isRewritable(range.getBegin())) return true;
   if (!isRewritable(range.getEnd())) return true;
   if (!isRewritable(parentIndent)) return true;
@@ -330,7 +365,7 @@
 
   if (StartFileID != EndFileID || StartFileID != parentFileID)
     return true;
-  if (StartOff >= EndOff || parentOff >= StartOff)
+  if (StartOff > EndOff)
     return true;
 
   FileID FID = StartFileID;
@@ -343,16 +378,12 @@
   const SrcMgr::ContentCache *
       Content = SourceMgr->getSLocEntry(FID).getFile().getContentCache();
   
-  // Find where the line starts for the three offsets.
+  // Find where the lines start.
   unsigned parentLineOffs = Content->SourceLineCache[parentLineNo];
   unsigned startLineOffs = Content->SourceLineCache[startLineNo];
-  unsigned endLineOffs = Content->SourceLineCache[endLineNo];
-
-  if (startLineOffs == endLineOffs || startLineOffs == parentLineOffs)
-    return true;
 
   // Find the whitespace at the start of each line.
-  StringRef parentSpace, startSpace, endSpace;
+  StringRef parentSpace, startSpace;
   {
     unsigned i = parentLineOffs;
     while (isWhitespace(MB[i]))
@@ -363,11 +394,6 @@
     while (isWhitespace(MB[i]))
       ++i;
     startSpace = MB.substr(startLineOffs, i-startLineOffs);
-
-    i = endLineOffs;
-    while (isWhitespace(MB[i]))
-      ++i;
-    endSpace = MB.substr(endLineOffs, i-endLineOffs);
   }
   if (parentSpace.size() >= startSpace.size())
     return true;
@@ -378,19 +404,14 @@
 
   // Indent the lines between start/end offsets.
   RewriteBuffer &RB = getEditBuffer(FID);
-  for (unsigned i = startLineOffs; i != endLineOffs; ++i) {
-    if (MB[i] == '\n') {
-      unsigned startOfLine = i+1;
-      if (startOfLine == endLineOffs)
-        break;
-      StringRef origIndent;
-      unsigned ws = startOfLine;
-      while (isWhitespace(MB[ws]))
-        ++ws;
-      origIndent = MB.substr(startOfLine, ws-startOfLine);
-      if (origIndent.startswith(startSpace))
-        RB.InsertText(startOfLine, indent, /*InsertAfter=*/false);
-    }
+  for (unsigned lineNo = startLineNo; lineNo <= endLineNo; ++lineNo) {
+    unsigned offs = Content->SourceLineCache[lineNo];
+    unsigned i = offs;
+    while (isWhitespace(MB[i]))
+      ++i;
+    StringRef origIndent = MB.substr(offs, i-offs);
+    if (origIndent.startswith(startSpace))
+      RB.InsertText(offs, indent, /*InsertAfter=*/false);
   }
 
   return false;