18bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner//===--- Rewriter.h - Code rewriting interface ------------------*- C++ -*-===//
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#ifndef LLVM_CLANG_REWRITER_H
168bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner#define LLVM_CLANG_REWRITER_H
178bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner
188a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner#include "clang/Basic/SourceLocation.h"
19305c613af6cfc40e519c75d9d2c84c6fa9a841c0Ted Kremenek#include "clang/Rewrite/Core/DeltaTree.h"
20305c613af6cfc40e519c75d9d2c84c6fa9a841c0Ted Kremenek#include "clang/Rewrite/Core/RewriteRope.h"
210ade808e0ac411baa2dbc1f76ad352b9b6d6d3f8Nick Lewycky#include "llvm/ADT/StringRef.h"
22329f0f5df1a4b45740312a53b8d01e32a76c91a5Ted Kremenek#include <cstring>
230ade808e0ac411baa2dbc1f76ad352b9b6d6d3f8Nick Lewycky#include <map>
24329f0f5df1a4b45740312a53b8d01e32a76c91a5Ted Kremenek#include <string>
250ade808e0ac411baa2dbc1f76ad352b9b6d6d3f8Nick Lewycky
268bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattnernamespace clang {
272c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner  class LangOptions;
288a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  class Rewriter;
29d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  class SourceManager;
3001c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  class Stmt;
311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
328bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
338bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner/// input with modifications get a new RewriteBuffer associated with them.  The
348bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner/// RewriteBuffer captures the modified text itself as well as information used
358bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner/// to map between SourceLocation's in the original input and offsets in the
368bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner/// RewriteBuffer.  For example, if text is inserted into the buffer, any
378bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner/// locations after the insertion point have to be mapped.
388bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattnerclass RewriteBuffer {
398a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  friend class Rewriter;
408bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner  /// Deltas - Keep track of all the deltas in the source code due to insertions
4177257889f5829144767c8a1d7fc18a929a377b5cChris Lattner  /// and deletions.
425c9dc5ac75de8d620311cdc20223998e0293d61fChris Lattner  DeltaTree Deltas;
4360c9c305a8f47cb1e6d4aa174e90e80355c4d415Alp Toker  RewriteRope Buffer;
448bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattnerpublic:
4560c9c305a8f47cb1e6d4aa174e90e80355c4d415Alp Toker  typedef RewriteRope::const_iterator iterator;
467c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  iterator begin() const { return Buffer.begin(); }
477c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  iterator end() const { return Buffer.end(); }
48b9bc3eca218e2670f05b34c0b3c33a46d710bd88Chris Lattner  unsigned size() const { return Buffer.size(); }
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
50d088a5f966c31462280d5ace29febc6889834611Edwin Vane  /// \brief Write to \p Stream the result of applying all changes to the
51d088a5f966c31462280d5ace29febc6889834611Edwin Vane  /// original buffer.
5298b303cfd3edb82653f0534cdcaa87c582a3ddbdAlp Toker  /// Note that it isn't safe to use this function to overwrite memory mapped
5398b303cfd3edb82653f0534cdcaa87c582a3ddbdAlp Toker  /// files in-place (PR17960). Consider using a higher-level utility such as
5498b303cfd3edb82653f0534cdcaa87c582a3ddbdAlp Toker  /// Rewriter::overwriteChangedFiles() instead.
55d088a5f966c31462280d5ace29febc6889834611Edwin Vane  ///
56d088a5f966c31462280d5ace29febc6889834611Edwin Vane  /// The original buffer is not actually changed.
57d088a5f966c31462280d5ace29febc6889834611Edwin Vane  raw_ostream &write(raw_ostream &Stream) const;
580ade808e0ac411baa2dbc1f76ad352b9b6d6d3f8Nick Lewycky
598bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner  /// RemoveText - Remove the specified text.
60b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  void RemoveText(unsigned OrigOffset, unsigned Size,
61b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis                  bool removeLineIfEmpty = false);
621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
638bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner  /// InsertText - Insert some text at the specified point, where the offset in
64886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  /// the buffer is specified relative to the original SourceBuffer.  The
65886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  /// text is inserted after the specified location.
668bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner  ///
67686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  void InsertText(unsigned OrigOffset, StringRef Str,
68886c8db545170850f7806f47b5f6120864effd09Ted Kremenek                  bool InsertAfter = true);
691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70886c8db545170850f7806f47b5f6120864effd09Ted Kremenek
71f3cd67369289014929ccc8431aaea536adade001Daniel Dunbar  /// InsertTextBefore - Insert some text before the specified point, where the
72f3cd67369289014929ccc8431aaea536adade001Daniel Dunbar  /// offset in the buffer is specified relative to the original
73f3cd67369289014929ccc8431aaea536adade001Daniel Dunbar  /// SourceBuffer. The text is inserted before the specified location.  This is
74f3cd67369289014929ccc8431aaea536adade001Daniel Dunbar  /// method is the same as InsertText with "InsertAfter == false".
75686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  void InsertTextBefore(unsigned OrigOffset, StringRef Str) {
76d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar    InsertText(OrigOffset, Str, false);
77886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  }
781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
79f3cd67369289014929ccc8431aaea536adade001Daniel Dunbar  /// InsertTextAfter - Insert some text at the specified point, where the
80f3cd67369289014929ccc8431aaea536adade001Daniel Dunbar  /// offset in the buffer is specified relative to the original SourceBuffer.
81f3cd67369289014929ccc8431aaea536adade001Daniel Dunbar  /// The text is inserted after the specified location.
82686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  void InsertTextAfter(unsigned OrigOffset, StringRef Str) {
83d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar    InsertText(OrigOffset, Str);
84886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  }
851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
867c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  /// ReplaceText - This method replaces a range of characters in the input
877c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  /// buffer with a new string.  This is effectively a combined "remove/insert"
887c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  /// operation.
897c239606f3a7a685653a0a7e64459c3f43522666Chris Lattner  void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
90686775deca8b8685eb90801495880e3abdd844c2Chris Lattner                   StringRef NewStr);
911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
92735271479ac57c27f744806859efd5b001dea248Chris Lattnerprivate:  // Methods only usable by Rewriter.
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
94735271479ac57c27f744806859efd5b001dea248Chris Lattner  /// Initialize - Start this rewrite buffer out with a copy of the unmodified
95735271479ac57c27f744806859efd5b001dea248Chris Lattner  /// input buffer.
96735271479ac57c27f744806859efd5b001dea248Chris Lattner  void Initialize(const char *BufStart, const char *BufEnd) {
97735271479ac57c27f744806859efd5b001dea248Chris Lattner    Buffer.assign(BufStart, BufEnd);
98735271479ac57c27f744806859efd5b001dea248Chris Lattner  }
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100735271479ac57c27f744806859efd5b001dea248Chris Lattner  /// getMappedOffset - Given an offset into the original SourceBuffer that this
101735271479ac57c27f744806859efd5b001dea248Chris Lattner  /// RewriteBuffer is based on, map it into the offset space of the
102735271479ac57c27f744806859efd5b001dea248Chris Lattner  /// RewriteBuffer.  If AfterInserts is true and if the OrigOffset indicates a
103735271479ac57c27f744806859efd5b001dea248Chris Lattner  /// position where text is inserted, the location returned will be after any
104735271479ac57c27f744806859efd5b001dea248Chris Lattner  /// inserted text at the position.
105735271479ac57c27f744806859efd5b001dea248Chris Lattner  unsigned getMappedOffset(unsigned OrigOffset,
106735271479ac57c27f744806859efd5b001dea248Chris Lattner                           bool AfterInserts = false) const{
107a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman    return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset;
108735271479ac57c27f744806859efd5b001dea248Chris Lattner  }
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
110a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman  /// AddInsertDelta - When an insertion is made at a position, this
111a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman  /// method is used to record that information.
112a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman  void AddInsertDelta(unsigned OrigOffset, int Change) {
113a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman    return Deltas.AddDelta(2*OrigOffset, Change);
114a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman  }
115a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman
116a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman  /// AddReplaceDelta - When a replacement/deletion is made at a position, this
117a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman  /// method is used to record that information.
118a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman  void AddReplaceDelta(unsigned OrigOffset, int Change) {
119a0978c24829dfd552d38fc3bae2b86e18bb90d49Eli Friedman    return Deltas.AddDelta(2*OrigOffset+1, Change);
120735271479ac57c27f744806859efd5b001dea248Chris Lattner  }
1218bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner};
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1238a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner
1248a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner/// Rewriter - This is the main interface to the rewrite buffers.  Its primary
1258a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner/// job is to dispatch high-level requests to the low-level RewriteBuffers that
1268a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner/// are involved.
1278bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattnerclass Rewriter {
1282c64b7b9381be4ff62fbdc404ed3f14c8086898dChris Lattner  SourceManager *SourceMgr;
1292c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner  const LangOptions *LangOpts;
1302b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  std::map<FileID, RewriteBuffer> RewriteBuffers;
1318bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattnerpublic:
132fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis  struct RewriteOptions {
133fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    /// \brief Given a source range, true to include previous inserts at the
134fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    /// beginning of the range as part of the range itself (true by default).
135fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    bool IncludeInsertsAtBeginOfRange;
136fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    /// \brief Given a source range, true to include previous inserts at the
137fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    /// end of the range as part of the range itself (true by default).
138fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    bool IncludeInsertsAtEndOfRange;
139fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    /// \brief If true and removing some text leaves a blank line
140fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    /// also remove the empty line (false by default).
141fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    bool RemoveLineIfEmpty;
142fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis
143fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    RewriteOptions()
144fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis      : IncludeInsertsAtBeginOfRange(true),
145fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis        IncludeInsertsAtEndOfRange(true),
146fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis        RemoveLineIfEmpty(false) { }
147fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis  };
148fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis
149d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  typedef std::map<FileID, RewriteBuffer>::iterator buffer_iterator;
150a87ce261dd9fd24609e1aff77fe575f46a781f17Edwin Vane  typedef std::map<FileID, RewriteBuffer>::const_iterator const_buffer_iterator;
151d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky
1522c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner  explicit Rewriter(SourceManager &SM, const LangOptions &LO)
1532c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner    : SourceMgr(&SM), LangOpts(&LO) {}
1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  explicit Rewriter() : SourceMgr(nullptr), LangOpts(nullptr) {}
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1562c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner  void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
1572c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner    SourceMgr = &SM;
1582c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner    LangOpts = &LO;
1592c78b873f4f3823ae859c15674cb3d76c8554113Chris Lattner  }
160aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor  SourceManager &getSourceMgr() const { return *SourceMgr; }
161aee526e77657afd1600276450e9c346953ad51d7Douglas Gregor  const LangOptions &getLangOpts() const { return *LangOpts; }
1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1638a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  /// isRewritable - Return true if this location is a raw file location, which
1648a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  /// is rewritable.  Locations from macros, etc are not rewritable.
1658a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  static bool isRewritable(SourceLocation Loc) {
1668a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner    return Loc.isFileID();
1678a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  }
168311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner
169311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner  /// getRangeSize - Return the size in bytes of the specified range if they
170311ff02fae0392bee6abe7723cdf5a69b2899a47Chris Lattner  /// are in the same file.  If not, this returns -1.
171fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis  int getRangeSize(SourceRange Range,
172fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis                   RewriteOptions opts = RewriteOptions()) const;
173fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis  int getRangeSize(const CharSourceRange &Range,
174fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis                   RewriteOptions opts = RewriteOptions()) const;
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1766a12a14a529a79524e17889046c7098b80a73c49Ted Kremenek  /// getRewrittenText - Return the rewritten form of the text in the specified
177b5cd09a2bf1509167a2e7a46bdd0316812a93335Chris Lattner  /// range.  If the start or end of the range was unrewritable or if they are
1787a02344d9b45db3719adabf8118887253fe944e4Chris Lattner  /// in different buffers, this returns an empty string.
1797a02344d9b45db3719adabf8118887253fe944e4Chris Lattner  ///
1807a02344d9b45db3719adabf8118887253fe944e4Chris Lattner  /// Note that this method is not particularly efficient.
1817a02344d9b45db3719adabf8118887253fe944e4Chris Lattner  ///
1826a12a14a529a79524e17889046c7098b80a73c49Ted Kremenek  std::string getRewrittenText(SourceRange Range) const;
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1848a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  /// InsertText - Insert the specified string at the specified location in the
185dcbc5b0b0722282a0fdd829359fe0d7e22adb882Chris Lattner  /// original buffer.  This method returns true (and does nothing) if the input
186dcbc5b0b0722282a0fdd829359fe0d7e22adb882Chris Lattner  /// location was not rewritable, false otherwise.
187f85e193739c953358c865005855253af4f68a497John McCall  ///
188f85e193739c953358c865005855253af4f68a497John McCall  /// \param indentNewLines if true new lines in the string are indented
1891824d54df85a462ada812dadda18130f951d40f3Dmitri Gribenko  /// using the indentation of the source line in position \p Loc.
190686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  bool InsertText(SourceLocation Loc, StringRef Str,
191f85e193739c953358c865005855253af4f68a497John McCall                  bool InsertAfter = true, bool indentNewLines = false);
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
193886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  /// InsertTextAfter - Insert the specified string at the specified location in
1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ///  the original buffer.  This method returns true (and does nothing) if
195886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  ///  the input location was not rewritable, false otherwise.  Text is
196886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  ///  inserted after any other text that has been previously inserted
197886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  ///  at the some point (the default behavior for InsertText).
198686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  bool InsertTextAfter(SourceLocation Loc, StringRef Str) {
1997cd830be364eaf98d9c9279e0d58b52dcde614c5Daniel Dunbar    return InsertText(Loc, Str);
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
202b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// \brief Insert the specified string after the token in the
203b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// specified location.
204686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  bool InsertTextAfterToken(SourceLocation Loc, StringRef Str);
205b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis
206886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  /// InsertText - Insert the specified string at the specified location in the
207886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  /// original buffer.  This method returns true (and does nothing) if the input
208886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  /// location was not rewritable, false otherwise.  Text is
209886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  /// inserted before any other text that has been previously inserted
210886c8db545170850f7806f47b5f6120864effd09Ted Kremenek  /// at the some point.
211686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  bool InsertTextBefore(SourceLocation Loc, StringRef Str) {
212d7407dc92c7d19cafce429e7e1cf9819d3fc0b92Daniel Dunbar    return InsertText(Loc, Str, false);
213329f0f5df1a4b45740312a53b8d01e32a76c91a5Ted Kremenek  }
2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
215aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattner  /// RemoveText - Remove the specified text region.
216b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  bool RemoveText(SourceLocation Start, unsigned Length,
217fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis                  RewriteOptions opts = RewriteOptions());
218b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis
219b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// \brief Remove the specified text region.
220fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis  bool RemoveText(CharSourceRange range,
221fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis                  RewriteOptions opts = RewriteOptions()) {
222fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    return RemoveText(range.getBegin(), getRangeSize(range, opts), opts);
223b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  }
224b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis
225b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// \brief Remove the specified text region.
226fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis  bool RemoveText(SourceRange range, RewriteOptions opts = RewriteOptions()) {
227fd183ba0b16718ff05e161bc479678e447df4999Argyrios Kyrtzidis    return RemoveText(range.getBegin(), getRangeSize(range, opts), opts);
228b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  }
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
230cde8bc49a19bdb18643085e87bf1135d0a6672c0Chris Lattner  /// ReplaceText - This method replaces a range of characters in the input
231cde8bc49a19bdb18643085e87bf1135d0a6672c0Chris Lattner  /// buffer with a new string.  This is effectively a combined "remove/insert"
232cde8bc49a19bdb18643085e87bf1135d0a6672c0Chris Lattner  /// operation.
233aadaf78d65daef3ac1b45e4ad6136ce859962fe2Chris Lattner  bool ReplaceText(SourceLocation Start, unsigned OrigLength,
234686775deca8b8685eb90801495880e3abdd844c2Chris Lattner                   StringRef NewStr);
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
236b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// ReplaceText - This method replaces a range of characters in the input
237b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// buffer with a new string.  This is effectively a combined "remove/insert"
238b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// operation.
239686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  bool ReplaceText(SourceRange range, StringRef NewStr) {
240b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis    return ReplaceText(range.getBegin(), getRangeSize(range), NewStr);
241b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  }
242b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis
243b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// ReplaceText - This method replaces a range of characters in the input
244b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// buffer with a new string.  This is effectively a combined "remove/insert"
245b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  /// operation.
246b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis  bool ReplaceText(SourceRange range, SourceRange replacementRange);
247b65ed34ebf0380c001756eea7a1c1d01e110b557Argyrios Kyrtzidis
24801c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
24901c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  /// printer to generate the replacement code.  This returns true if the input
25001c5748c29e75b29cab5fc7d8ad1b173b29c7ecfChris Lattner  /// could not be rewritten, or false if successful.
25188906cddbb1d5b3a868eeeec6cb170befc829c2fFariborz Jahanian  bool ReplaceStmt(Stmt *From, Stmt *To);
25210c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis
25310c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis  /// \brief Increase indentation for the lines between the given source range.
25410c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis  /// To determine what the indentation should be, 'parentIndent' is used
25510c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis  /// that should be at a source location with an indentation one degree
25610c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis  /// lower than the given range.
25710c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis  bool IncreaseIndentation(CharSourceRange range, SourceLocation parentIndent);
25810c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis  bool IncreaseIndentation(SourceRange range, SourceLocation parentIndent) {
25910c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis    return IncreaseIndentation(CharSourceRange::getTokenRange(range),
26010c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis                               parentIndent);
26110c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis  }
26210c8d9e63bcc96d55f788e7c08b72ce626c8aeecArgyrios Kyrtzidis
2631d015313b27f6002b1c4a74e478ede1622141b4eFariborz Jahanian  /// ConvertToString converts statement 'From' to a string using the
264d762357055f3d82959604743dbff20ca337e04beFariborz Jahanian  /// pretty printer.
2651d015313b27f6002b1c4a74e478ede1622141b4eFariborz Jahanian  std::string ConvertToString(Stmt *From);
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
267d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  /// getEditBuffer - This is like getRewriteBufferFor, but always returns a
268d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  /// buffer, and allows you to write on it directly.  This is useful if you
269d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  /// want efficient low-level access to apis for scribbling on one specific
270d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  /// FileID's buffer.
271d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  RewriteBuffer &getEditBuffer(FileID FID);
272d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky
2738a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
2748a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  /// If no modification has been made to it, return null.
2752b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
2762b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner    std::map<FileID, RewriteBuffer>::const_iterator I =
2772b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner      RewriteBuffers.find(FID);
2786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return I == RewriteBuffers.end() ? nullptr : &I->second;
2798a12c2777cccdf629b89745b6ecc89a8c1641e4eChris Lattner  }
2806837e38d4301d7874805ed4b24d8d14662789e10Chris Lattner
281d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  // Iterators over rewrite buffers.
282d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  buffer_iterator buffer_begin() { return RewriteBuffers.begin(); }
283d4a97a18ea3cda3ba095e7c0c6708e7a39cf31dbNick Lewycky  buffer_iterator buffer_end() { return RewriteBuffers.end(); }
284a87ce261dd9fd24609e1aff77fe575f46a781f17Edwin Vane  const_buffer_iterator buffer_begin() const { return RewriteBuffers.begin(); }
285a87ce261dd9fd24609e1aff77fe575f46a781f17Edwin Vane  const_buffer_iterator buffer_end() const { return RewriteBuffers.end(); }
2866837e38d4301d7874805ed4b24d8d14662789e10Chris Lattner
287ad8070b6bddf2867fd3aba8354cff7016e568758Nick Lewycky  /// overwriteChangedFiles - Save all changed files to disk.
288bfbfee51ec8f20f3f1b9f8329705d816b67438e7Manuel Klimek  ///
2896bf97fb15c09db9a0238ccb73be2dbf9cd77a7eeAlp Toker  /// Returns true if any files were not saved successfully.
290bfbfee51ec8f20f3f1b9f8329705d816b67438e7Manuel Klimek  /// Outputs diagnostics via the source manager's diagnostic engine
291bfbfee51ec8f20f3f1b9f8329705d816b67438e7Manuel Klimek  /// in case of an error.
292bfbfee51ec8f20f3f1b9f8329705d816b67438e7Manuel Klimek  bool overwriteChangedFiles();
293bfbfee51ec8f20f3f1b9f8329705d816b67438e7Manuel Klimek
2946837e38d4301d7874805ed4b24d8d14662789e10Chris Lattnerprivate:
2952b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner  unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
2968bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner};
2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2988bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner} // end namespace clang
2998bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner
3008bd12b848bc353a9d34b54144c3dd3407b064292Chris Lattner#endif
301