 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
100.0% |
2 / 2 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
100.0% |
2 / 2 |
| |
|
Line Coverage: |
100.0% |
38 / 38 |
| |
 |
|
 |
1 : //===--- Rewriter.h - Code rewriting interface ------------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines the Rewriter class, which is used for code
11 : // transformations.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_CLANG_REWRITER_H
16 : #define LLVM_CLANG_REWRITER_H
17 :
18 : #include "clang/Basic/SourceLocation.h"
19 : #include "clang/Rewrite/RewriteRope.h"
20 : #include <map>
21 : #include <vector>
22 : #include <cstring>
23 : #include <string>
24 : #include "clang/Rewrite/DeltaTree.h"
25 : #include "llvm/ADT/StringRef.h"
26 :
27 : namespace clang {
28 : class SourceManager;
29 : class LangOptions;
30 : class Rewriter;
31 : class Stmt;
32 :
33 : /// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
34 : /// input with modifications get a new RewriteBuffer associated with them. The
35 : /// RewriteBuffer captures the modified text itself as well as information used
36 : /// to map between SourceLocation's in the original input and offsets in the
37 : /// RewriteBuffer. For example, if text is inserted into the buffer, any
38 : /// locations after the insertion point have to be mapped.
39 536: class RewriteBuffer {
40 : friend class Rewriter;
41 : /// Deltas - Keep track of all the deltas in the source code due to insertions
42 : /// and deletions.
43 : DeltaTree Deltas;
44 :
45 : /// Buffer - This is the actual buffer itself. Note that using a vector or
46 : /// string is a horribly inefficient way to do this, we should use a rope
47 : /// instead.
48 : typedef RewriteRope BufferTy;
49 : BufferTy Buffer;
50 : public:
51 : typedef BufferTy::const_iterator iterator;
52 94: iterator begin() const { return Buffer.begin(); }
53 64: iterator end() const { return Buffer.end(); }
54 6: unsigned size() const { return Buffer.size(); }
55 :
56 : /// RemoveText - Remove the specified text.
57 : void RemoveText(unsigned OrigOffset, unsigned Size);
58 :
59 : /// InsertText - Insert some text at the specified point, where the offset in
60 : /// the buffer is specified relative to the original SourceBuffer. The
61 : /// text is inserted after the specified location.
62 : ///
63 : void InsertText(unsigned OrigOffset, const llvm::StringRef &Str,
64 : bool InsertAfter = true);
65 :
66 :
67 : /// InsertTextBefore - Insert some text before the specified point, where the
68 : /// offset in the buffer is specified relative to the original
69 : /// SourceBuffer. The text is inserted before the specified location. This is
70 : /// method is the same as InsertText with "InsertAfter == false".
71 118: void InsertTextBefore(unsigned OrigOffset, const llvm::StringRef &Str) {
72 118: InsertText(OrigOffset, Str, false);
73 118: }
74 :
75 : /// InsertTextAfter - Insert some text at the specified point, where the
76 : /// offset in the buffer is specified relative to the original SourceBuffer.
77 : /// The text is inserted after the specified location.
78 43: void InsertTextAfter(unsigned OrigOffset, const llvm::StringRef &Str) {
79 43: InsertText(OrigOffset, Str);
80 43: }
81 :
82 : /// ReplaceText - This method replaces a range of characters in the input
83 : /// buffer with a new string. This is effectively a combined "remove/insert"
84 : /// operation.
85 : void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
86 : const llvm::StringRef &NewStr);
87 :
88 : private: // Methods only usable by Rewriter.
89 :
90 : /// Initialize - Start this rewrite buffer out with a copy of the unmodified
91 : /// input buffer.
92 67: void Initialize(const char *BufStart, const char *BufEnd) {
93 67: Buffer.assign(BufStart, BufEnd);
94 67: }
95 :
96 : /// getMappedOffset - Given an offset into the original SourceBuffer that this
97 : /// RewriteBuffer is based on, map it into the offset space of the
98 : /// RewriteBuffer. If AfterInserts is true and if the OrigOffset indicates a
99 : /// position where text is inserted, the location returned will be after any
100 : /// inserted text at the position.
101 : unsigned getMappedOffset(unsigned OrigOffset,
102 1637: bool AfterInserts = false) const{
103 1637: return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset;
104 : }
105 :
106 : /// AddInsertDelta - When an insertion is made at a position, this
107 : /// method is used to record that information.
108 649: void AddInsertDelta(unsigned OrigOffset, int Change) {
109 649: return Deltas.AddDelta(2*OrigOffset, Change);
110 : }
111 :
112 : /// AddReplaceDelta - When a replacement/deletion is made at a position, this
113 : /// method is used to record that information.
114 508: void AddReplaceDelta(unsigned OrigOffset, int Change) {
115 508: return Deltas.AddDelta(2*OrigOffset+1, Change);
116 : }
117 : };
118 :
119 :
120 : /// Rewriter - This is the main interface to the rewrite buffers. Its primary
121 : /// job is to dispatch high-level requests to the low-level RewriteBuffers that
122 : /// are involved.
123 68: class Rewriter {
124 : SourceManager *SourceMgr;
125 : const LangOptions *LangOpts;
126 : std::map<FileID, RewriteBuffer> RewriteBuffers;
127 : public:
128 13: explicit Rewriter(SourceManager &SM, const LangOptions &LO)
129 13: : SourceMgr(&SM), LangOpts(&LO) {}
130 55: explicit Rewriter() : SourceMgr(0), LangOpts(0) {}
131 :
132 55: void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
133 55: SourceMgr = &SM;
134 55: LangOpts = &LO;
135 55: }
136 47: SourceManager &getSourceMgr() { return *SourceMgr; }
137 7: const LangOptions &getLangOpts() { return *LangOpts; }
138 :
139 : /// isRewritable - Return true if this location is a raw file location, which
140 : /// is rewritable. Locations from macros, etc are not rewritable.
141 1590: static bool isRewritable(SourceLocation Loc) {
142 1590: return Loc.isFileID();
143 : }
144 :
145 : /// getRangeSize - Return the size in bytes of the specified range if they
146 : /// are in the same file. If not, this returns -1.
147 : int getRangeSize(SourceRange Range) const;
148 :
149 : /// getRewrittenText - Return the rewritten form of the text in the specified
150 : /// range. If the start or end of the range was unrewritable or if they are
151 : /// in different buffers, this returns an empty string.
152 : ///
153 : /// Note that this method is not particularly efficient.
154 : ///
155 : std::string getRewrittenText(SourceRange Range) const;
156 :
157 : /// InsertText - Insert the specified string at the specified location in the
158 : /// original buffer. This method returns true (and does nothing) if the input
159 : /// location was not rewritable, false otherwise.
160 : bool InsertText(SourceLocation Loc, const llvm::StringRef &Str,
161 : bool InsertAfter = true);
162 :
163 : /// InsertTextAfter - Insert the specified string at the specified location in
164 : /// the original buffer. This method returns true (and does nothing) if
165 : /// the input location was not rewritable, false otherwise. Text is
166 : /// inserted after any other text that has been previously inserted
167 : /// at the some point (the default behavior for InsertText).
168 4: bool InsertTextAfter(SourceLocation Loc, const llvm::StringRef &Str) {
169 4: return InsertText(Loc, Str);
170 : }
171 :
172 : /// InsertText - Insert the specified string at the specified location in the
173 : /// original buffer. This method returns true (and does nothing) if the input
174 : /// location was not rewritable, false otherwise. Text is
175 : /// inserted before any other text that has been previously inserted
176 : /// at the some point.
177 39: bool InsertTextBefore(SourceLocation Loc, const llvm::StringRef &Str) {
178 39: return InsertText(Loc, Str, false);
179 : }
180 :
181 : /// RemoveText - Remove the specified text region.
182 : bool RemoveText(SourceLocation Start, unsigned Length);
183 :
184 : /// ReplaceText - This method replaces a range of characters in the input
185 : /// buffer with a new string. This is effectively a combined "remove/insert"
186 : /// operation.
187 : bool ReplaceText(SourceLocation Start, unsigned OrigLength,
188 : const llvm::StringRef &NewStr);
189 :
190 : /// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
191 : /// printer to generate the replacement code. This returns true if the input
192 : /// could not be rewritten, or false if successful.
193 : bool ReplaceStmt(Stmt *From, Stmt *To);
194 :
195 : /// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
196 : /// If no modification has been made to it, return null.
197 62: const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
198 : std::map<FileID, RewriteBuffer>::const_iterator I =
199 62: RewriteBuffers.find(FID);
1: branch 2 taken
61: branch 3 taken
200 62: return I == RewriteBuffers.end() ? 0 : &I->second;
201 : }
202 :
203 : /// getEditBuffer - This is like getRewriteBufferFor, but always returns a
204 : /// buffer, and allows you to write on it directly. This is useful if you
205 : /// want efficient low-level access to apis for scribbling on one specific
206 : /// FileID's buffer.
207 : RewriteBuffer &getEditBuffer(FileID FID);
208 :
209 : private:
210 : unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;
211 : };
212 :
213 : } // end namespace clang
214 :
215 : #endif
Generated: 2010-02-10 01:31 by zcov