Rewriter.cpp revision 6a12a14a529a79524e17889046c7098b80a73c49
18bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//===--- Rewriter.cpp - Code rewriting interface --------------------------===//
28bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//
38bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//                     The LLVM Compiler Infrastructure
48bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
78bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//
88bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//===----------------------------------------------------------------------===//
98bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//
108bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//  This file defines the Rewriter class, which is used for code
118bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//  transformations.
128bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//
138bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//===----------------------------------------------------------------------===//
148bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner
158bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner#include "clang/Rewrite/Rewriter.h"
1601c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner#include "clang/AST/Stmt.h"
172c3352b5d1f5f4546af2f3051a304d84d57c697eTed Kremenek#include "clang/AST/Decl.h"
189d62a5b31ec3762f416cc9ef89d1b7b433d13ac5Chris Lattner#include "clang/Lex/Lexer.h"
198a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner#include "clang/Basic/SourceManager.h"
20a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek#include "llvm/Support/raw_ostream.h"
218bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattnerusing namespace clang;
228bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner
238bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattnervoid RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size) {
247c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  // Nothing to remove, exit early.
257c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  if (Size == 0) return;
267c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner
277c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  unsigned RealOffset = getMappedOffset(OrigOffset, true);
287c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  assert(RealOffset+Size < Buffer.size() && "Invalid location");
291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
307c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  // Remove the dead characters.
31febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  Buffer.erase(RealOffset, Size);
327c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner
337c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  // Add a delta so that future changes are offset correctly.
34a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman  AddReplaceDelta(OrigOffset, -Size);
358bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner}
368bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner
37d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbarvoid RewriteBuffer::InsertText(unsigned OrigOffset, const llvm::StringRef &Str,
38886c8db545170850f7806f47b5f6120864effd09Ted Kremenek                               bool InsertAfter) {
391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4003b071043593590b01fdf61df3e29c0ae7c067d3Chris Lattner  // Nothing to insert, exit early.
41d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar  if (Str.empty()) return;
42febe719596ee68605944da5f2e03258e18e6df8cChris Lattner
43886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);
44d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar  Buffer.insert(RealOffset, Str.begin(), Str.end());
451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4603b071043593590b01fdf61df3e29c0ae7c067d3Chris Lattner  // Add a delta so that future changes are offset correctly.
47d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar  AddInsertDelta(OrigOffset, Str.size());
488bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner}
498a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner
507c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner/// ReplaceText - This method replaces a range of characters in the input
51febe719596ee68605944da5f2e03258e18e6df8cChris Lattner/// buffer with a new string.  This is effectively a combined "remove+insert"
527c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner/// operation.
537c239606f3a7a685653a0a7e64459c3f43522666Chris Lattnervoid RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,
54d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar                                const llvm::StringRef &NewStr) {
55a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman  unsigned RealOffset = getMappedOffset(OrigOffset, true);
56febe719596ee68605944da5f2e03258e18e6df8cChris Lattner  Buffer.erase(RealOffset, OrigLength);
57d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar  Buffer.insert(RealOffset, NewStr.begin(), NewStr.end());
58d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar  if (OrigLength != NewStr.size())
59d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar    AddReplaceDelta(OrigOffset, NewStr.size() - OrigLength);
607c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner}
618a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner
628a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner
638a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner//===----------------------------------------------------------------------===//
648a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner// Rewriter class
658a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner//===----------------------------------------------------------------------===//
668a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner
67311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner/// getRangeSize - Return the size in bytes of the specified range if they
68311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner/// are in the same file.  If not, this returns -1.
69311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattnerint Rewriter::getRangeSize(SourceRange Range) const {
70311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner  if (!isRewritable(Range.getBegin()) ||
71311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner      !isRewritable(Range.getEnd())) return -1;
721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
732b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  FileID StartFileID, EndFileID;
742b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  unsigned StartOff, EndOff;
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
76311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
77311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
79311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner  if (StartFileID != EndFileID)
80311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner    return -1;
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
82d6690b20b3340f30a225dffa49603951dcd75e4eChris Lattner  // If edits have been made to this buffer, the delta between the range may
83d6690b20b3340f30a225dffa49603951dcd75e4eChris Lattner  // have changed.
842b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  std::map<FileID, RewriteBuffer>::const_iterator I =
85075eb6eae0506e041e0086ddcab31ba2e55f0472Chris Lattner    RewriteBuffers.find(StartFileID);
86d6690b20b3340f30a225dffa49603951dcd75e4eChris Lattner  if (I != RewriteBuffers.end()) {
87075eb6eae0506e041e0086ddcab31ba2e55f0472Chris Lattner    const RewriteBuffer &RB = I->second;
88d6690b20b3340f30a225dffa49603951dcd75e4eChris Lattner    EndOff = RB.getMappedOffset(EndOff, true);
89d6690b20b3340f30a225dffa49603951dcd75e4eChris Lattner    StartOff = RB.getMappedOffset(StartOff);
90075eb6eae0506e041e0086ddcab31ba2e55f0472Chris Lattner  }
91075eb6eae0506e041e0086ddcab31ba2e55f0472Chris Lattner
921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
939d62a5b31ec3762f416cc9ef89d1b7b433d13ac5Chris Lattner  // Adjust the end offset to the end of the last token, instead of being the
949d62a5b31ec3762f416cc9ef89d1b7b433d13ac5Chris Lattner  // start of the last token.
952c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner  EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
97d6690b20b3340f30a225dffa49603951dcd75e4eChris Lattner  return EndOff-StartOff;
98311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner}
99311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner
1006a12a14a529a79524e17889046c7098b80a73c49Ted Kremenek/// getRewrittenText - Return the rewritten form of the text in the specified
101b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner/// range.  If the start or end of the range was unrewritable or if they are
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// in different buffers, this returns an empty string.
103b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner///
104b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner/// Note that this method is not particularly efficient.
105b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner///
1066a12a14a529a79524e17889046c7098b80a73c49Ted Kremenekstd::string Rewriter::getRewrittenText(SourceRange Range) const {
107b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  if (!isRewritable(Range.getBegin()) ||
108b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner      !isRewritable(Range.getEnd()))
109b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner    return "";
1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1112b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  FileID StartFileID, EndFileID;
1122b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  unsigned StartOff, EndOff;
113b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
114b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
116b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  if (StartFileID != EndFileID)
117b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner    return ""; // Start and end in different buffers.
1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
119b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  // If edits have been made to this buffer, the delta between the range may
120b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  // have changed.
1212b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  std::map<FileID, RewriteBuffer>::const_iterator I =
122b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner    RewriteBuffers.find(StartFileID);
123b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  if (I == RewriteBuffers.end()) {
124b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner    // If the buffer hasn't been rewritten, just return the text from the input.
125b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner    const char *Ptr = SourceMgr->getCharacterData(Range.getBegin());
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
127b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner    // Adjust the end offset to the end of the last token, instead of being the
128b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner    // start of the last token.
1292c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
130b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner    return std::string(Ptr, Ptr+EndOff-StartOff);
131b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  }
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
133b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  const RewriteBuffer &RB = I->second;
134b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  EndOff = RB.getMappedOffset(EndOff, true);
135b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  StartOff = RB.getMappedOffset(StartOff);
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
137b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  // Adjust the end offset to the end of the last token, instead of being the
138b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  // start of the last token.
1392c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner  EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
140b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner
141b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  // Advance the iterators to the right spot, yay for linear time algorithms.
142b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  RewriteBuffer::iterator Start = RB.begin();
143b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  std::advance(Start, StartOff);
144b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  RewriteBuffer::iterator End = Start;
145b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  std::advance(End, EndOff-StartOff);
1461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
147b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  return std::string(Start, End);
148b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner}
149311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner
1507c239606f3a7a685653a0a7e64459c3f43522666Chris Lattnerunsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
1512b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner                                              FileID &FID) const {
15254bd7cb491cce1fb55ce1baac40cf7002a317166Chris Lattner  assert(Loc.isValid() && "Invalid location");
153de7aeefc5573d669ed476d7bda7a8940d3bcadb7Chris Lattner  std::pair<FileID,unsigned> V = SourceMgr->getDecomposedLoc(Loc);
1542b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  FID = V.first;
1557c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  return V.second;
1567c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner}
1577c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner
1587c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner
1598a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner/// getEditBuffer - Get or create a RewriteBuffer for the specified FileID.
1608a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner///
1612b2453a7d8fe732561795431f39ceb2b2a832d84Chris LattnerRewriteBuffer &Rewriter::getEditBuffer(FileID FID) {
1622b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  std::map<FileID, RewriteBuffer>::iterator I =
1632b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner    RewriteBuffers.lower_bound(FID);
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (I != RewriteBuffers.end() && I->first == FID)
1658a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner    return I->second;
1662b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer()));
1671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1682b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  std::pair<const char*, const char*> MB = SourceMgr->getBufferData(FID);
1698a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  I->second.Initialize(MB.first, MB.second);
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1718a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  return I->second;
1728a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner}
1738a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner
17454a2f071a37ee63d3ef1d4e7ca2570542ee12115Chris Lattner/// InsertText - Insert the specified string at the specified location in the
175aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattner/// original buffer.
176d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbarbool Rewriter::InsertText(SourceLocation Loc, const llvm::StringRef &Str,
177d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar                          bool InsertAfter) {
178dcbc5b0b0722282a0fdd829359fe0d7e22adb882Chris Lattner  if (!isRewritable(Loc)) return true;
1792b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  FileID FID;
1802b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
181d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar  getEditBuffer(FID).InsertText(StartOffs, Str, InsertAfter);
182dcbc5b0b0722282a0fdd829359fe0d7e22adb882Chris Lattner  return false;
18354a2f071a37ee63d3ef1d4e7ca2570542ee12115Chris Lattner}
18454a2f071a37ee63d3ef1d4e7ca2570542ee12115Chris Lattner
185aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattner/// RemoveText - Remove the specified text region.
186aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattnerbool Rewriter::RemoveText(SourceLocation Start, unsigned Length) {
187aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattner  if (!isRewritable(Start)) return true;
1882b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  FileID FID;
1892b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  unsigned StartOffs = getLocationOffsetAndFileID(Start, FID);
1902b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  getEditBuffer(FID).RemoveText(StartOffs, Length);
191aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattner  return false;
192674af9541256dc3ef803e3723027a8b028f1f7a2Chris Lattner}
1938a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner
194674af9541256dc3ef803e3723027a8b028f1f7a2Chris Lattner/// ReplaceText - This method replaces a range of characters in the input
195674af9541256dc3ef803e3723027a8b028f1f7a2Chris Lattner/// buffer with a new string.  This is effectively a combined "remove/insert"
196674af9541256dc3ef803e3723027a8b028f1f7a2Chris Lattner/// operation.
197aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattnerbool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
198d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar                           const llvm::StringRef &NewStr) {
199aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattner  if (!isRewritable(Start)) return true;
2002b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  FileID StartFileID;
2017c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
2021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
203d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar  getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength, NewStr);
204aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattner  return false;
2058a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner}
20601c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner
20701c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner/// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
20801c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner/// printer to generate the replacement code.  This returns true if the input
20901c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner/// could not be rewritten, or false if successful.
21001c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattnerbool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) {
21101c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  // Measaure the old text.
21201c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  int Size = getRangeSize(From->getSourceRange());
21301c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  if (Size == -1)
21401c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner    return true;
2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21601c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  // Get the new text.
217a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek  std::string SStr;
218a95d3750441ac8ad03e36af8e6e74039c9a3109dTed Kremenek  llvm::raw_string_ostream S(SStr);
219e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  To->printPretty(S, 0, PrintingPolicy(*LangOpts));
22001c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  const std::string &Str = S.str();
22101c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner
222d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar  ReplaceText(From->getLocStart(), Size, Str);
22301c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  return false;
22401c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner}
22501c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner
22601c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner
227