16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/Twine.h"
19 using namespace clang;
34 Buf, SourceMgr, LangOpts);
36 if (!ArgName.empty()) {
37 II = &IdentTable.
get(ArgName);
41 void EditedSource::startingCommit() {}
43 void EditedSource::finishedCommit() {
44 for (
auto &ExpArg : CurrCommitMacroArgExps) {
47 std::tie(ExpLoc, II) = ExpArg;
49 if (std::find(ArgNames.begin(), ArgNames.end(), II) == ArgNames.end()) {
50 ArgNames.push_back(II);
53 CurrCommitMacroArgExps.clear();
63 if (FA != FileEdits.end()) {
64 if (FA->first != Offs)
68 if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
71 deconstructMacroArgLoc(OrigLoc, ExpLoc, II);
73 if (
I != ExpansionToArgMap.end() &&
74 std::find(
I->second.begin(),
I->second.end(), II) !=
I->second.end()) {
97 bool beforePreviousInsertions) {
103 if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
106 deconstructMacroArgLoc(OrigLoc, ExpLoc, II);
108 CurrCommitMacroArgExps.emplace_back(ExpLoc, II);
111 FileEdit &FA = FileEdits[Offs];
112 if (FA.Text.empty()) {
117 if (beforePreviousInsertions)
128 bool beforePreviousInsertions) {
136 if (I != FileEdits.begin())
139 for (; I != FileEdits.end(); ++
I) {
140 FileEdit &FA = I->second;
156 for (; I != FileEdits.end() && EndOffs > I->first; ++
I) {
157 FileEdit &FA = I->second;
163 StringRef text = getSourceText(BeginOffs, B, Invalid);
172 if (BeginOffs < EndOffs) {
174 StringRef text = getSourceText(BeginOffs, EndOffs, Invalid);
180 return commitInsert(OrigLoc, Offs, StrVec, beforePreviousInsertions);
190 if (I != FileEdits.begin())
193 for (; I != FileEdits.end(); ++
I) {
194 FileEdit &FA = I->second;
203 FileEdit *TopFA =
nullptr;
205 if (I == FileEdits.end()) {
207 NewI = FileEdits.insert(I, std::make_pair(BeginOffs, FileEdit()));
208 NewI->second.RemoveLen = Len;
212 FileEdit &FA = I->second;
217 NewI = FileEdits.insert(I, std::make_pair(BeginOffs, FileEdit()));
218 TopBegin = BeginOffs;
220 TopFA = &NewI->second;
221 TopFA->RemoveLen = Len;
226 if (TopEnd >= EndOffs)
230 TopFA->RemoveLen += diff;
232 TopFA->Text = StringRef();
236 while (I != FileEdits.end()) {
237 FileEdit &FA = I->second;
245 FileEdits.erase(I++);
252 TopFA->RemoveLen += diff;
267 Editor.startingCommit();
270 Editor.finishedCommit();
321 unsigned &len, StringRef &text) {
322 assert(len && text.empty());
324 if (BeginTokLoc != Loc)
327 bool Invalid =
false;
333 unsigned end = begin + len;
336 if (end == buffer.size())
339 assert(begin < buffer.size() && end < buffer.size() &&
"Invalid range!");
344 if (buffer[end] ==
' ')
349 if (buffer[end] ==
' ') {
350 assert((end + 1 != buffer.size() || buffer.data()[end + 1] == 0) &&
351 "buffer not zero-terminated!");
354 buffer.data()[end + 1],
360 if (!
canBeJoined(buffer[begin-1], buffer[end], LangOpts))
365 StringRef text,
FileOffset offs,
unsigned len,
370 assert(Loc.isFileID());
376 Loc.getLocWithOffset(len));
387 receiver.
insert(Loc, text);
395 if (FileEdits.empty())
400 StrVec = I->second.Text;
401 CurLen = I->second.RemoveLen;
407 FileEdit act = I->second;
408 assert(offs >= CurEnd);
410 if (offs == CurEnd) {
412 CurLen += act.RemoveLen;
417 applyRewrite(receiver, StrVec, CurOffs, CurLen, SourceMgr, LangOpts);
420 CurLen = act.RemoveLen;
424 applyRewrite(receiver, StrVec, CurOffs, CurLen, SourceMgr, LangOpts);
435 assert(BeginOffs <= EndOffs);
442 SourceMgr, LangOpts, &Invalid);
446 EditedSource::getActionForOffset(
FileOffset Offs) {
448 if (I == FileEdits.begin())
449 return FileEdits.end();
451 FileEdit &FA = I->second;
454 if (Offs >= B && Offs < E)
457 return FileEdits.end();
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer...
static LLVM_READONLY bool isWhitespace(unsigned char c)
Return true if this character is horizontal or vertical ASCII whitespace: ' ', '\t', '\f', '\v', '\n', '\r'.
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
Defines the SourceManager interface.
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
void applyRewrites(EditsReceiver &receiver)
static void applyRewrite(EditsReceiver &receiver, StringRef text, FileOffset offs, unsigned len, const SourceManager &SM, const LangOptions &LangOpts)
unsigned getOffset() const
FileOffset getWithOffset(unsigned offset) const
One of these records is kept for each identifier that is lexed.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
bool isCommitable() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
detail::InMemoryDirectory::const_iterator I
edit_iterator edit_begin() const
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
Represents a character-granular source range.
virtual void replace(CharSourceRange range, StringRef text)=0
FileOffset InsertFromRangeOffs
virtual void remove(CharSourceRange range)
By default it calls replace with an empty string.
edit_iterator edit_end() const
static CharSourceRange getCharRange(SourceRange R)
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
const TemplateArgument * iterator
static bool canBeJoined(char left, char right, const LangOptions &LangOpts)
SmallVectorImpl< Edit >::const_iterator edit_iterator
static SourceLocation GetBeginningOfToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Given a location any where in a source buffer, find the location that corresponds to the beginning of...
StringRef copyString(StringRef str)
std::pair< SourceLocation, SourceLocation > getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
detail::InMemoryDirectory::const_iterator E
bool commit(const Commit &commit)
static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts)
Returns true if the given character could appear in an identifier.
bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs)
static bool canRemoveWhitespace(char left, char beforeWSpace, char right, const LangOptions &LangOpts)
Returns true if it is ok to eliminate the trailing whitespace between the given characters.
virtual void insert(SourceLocation loc, StringRef text)=0
static void adjustRemoval(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation Loc, FileOffset offs, unsigned &len, StringRef &text)
Check the range that we are going to remove and: -Remove any trailing whitespace if possible...
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
This class handles loading and caching of source files into memory.