summaryrefslogtreecommitdiffstats
path: root/include/clang/Edit
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-03-06 20:06:33 +0000
committerTed Kremenek <kremenek@apple.com>2012-03-06 20:06:33 +0000
commit30660a898545416f0fea2d717f16f75640001e38 (patch)
treea8408d8c12d992b4110fca1bfe78f337b48f5d11 /include/clang/Edit
parent2a253960f0312c9759965a1defb9326d6b2764a4 (diff)
Add new code migrator support for migrating existing Objective-C code to use
the new Objective-C NSArray/NSDictionary/NSNumber literal syntax. This introduces a new library, libEdit, which provides a new way to support migration of code that improves on the original ARC migrator. We now believe that most of its functionality can be refactored into the existing libraries, and thus this new library may shortly disappear. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152141 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Edit')
-rw-r--r--include/clang/Edit/Commit.h140
-rw-r--r--include/clang/Edit/EditedSource.h87
-rw-r--r--include/clang/Edit/EditsReceiver.h35
-rw-r--r--include/clang/Edit/FileOffset.h65
-rw-r--r--include/clang/Edit/Rewriters.h33
5 files changed, 360 insertions, 0 deletions
diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h
new file mode 100644
index 0000000000..aaf6b18384
--- /dev/null
+++ b/include/clang/Edit/Commit.h
@@ -0,0 +1,140 @@
+//===----- Commit.h - A unit of edits ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_COMMIT_H
+#define LLVM_CLANG_EDIT_COMMIT_H
+
+#include "clang/Edit/FileOffset.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+ class LangOptions;
+ class PreprocessingRecord;
+
+namespace edit {
+ class EditedSource;
+
+class Commit {
+public:
+ enum EditKind {
+ Act_Insert,
+ Act_InsertFromRange,
+ Act_Remove
+ };
+
+ struct Edit {
+ EditKind Kind;
+ StringRef Text;
+ SourceLocation OrigLoc;
+ FileOffset Offset;
+ FileOffset InsertFromRangeOffs;
+ unsigned Length;
+ bool BeforePrev;
+
+ SourceLocation getFileLocation(SourceManager &SM) const;
+ CharSourceRange getFileRange(SourceManager &SM) const;
+ CharSourceRange getInsertFromRange(SourceManager &SM) const;
+ };
+
+private:
+ const SourceManager &SourceMgr;
+ const LangOptions &LangOpts;
+ const PreprocessingRecord *PPRec;
+ EditedSource *Editor;
+
+ bool IsCommitable;
+ SmallVector<Edit, 8> CachedEdits;
+
+public:
+ explicit Commit(EditedSource &Editor);
+ Commit(const SourceManager &SM, const LangOptions &LangOpts,
+ const PreprocessingRecord *PPRec = 0)
+ : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0),
+ IsCommitable(true) { }
+
+ bool isCommitable() const { return IsCommitable; }
+
+ bool insert(SourceLocation loc, StringRef text, bool afterToken = false,
+ bool beforePreviousInsertions = false);
+ bool insertAfterToken(SourceLocation loc, StringRef text,
+ bool beforePreviousInsertions = false) {
+ return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions);
+ }
+ bool insertBefore(SourceLocation loc, StringRef text) {
+ return insert(loc, text, /*afterToken=*/false,
+ /*beforePreviousInsertions=*/true);
+ }
+ bool insertFromRange(SourceLocation loc, CharSourceRange range,
+ bool afterToken = false,
+ bool beforePreviousInsertions = false);
+ bool insertWrap(StringRef before, CharSourceRange range, StringRef after);
+
+ bool remove(CharSourceRange range);
+
+ bool replace(CharSourceRange range, StringRef text);
+ bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange);
+ bool replaceText(SourceLocation loc, StringRef text,
+ StringRef replacementText);
+
+ bool insertFromRange(SourceLocation loc, SourceRange TokenRange,
+ bool afterToken = false,
+ bool beforePreviousInsertions = false) {
+ return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange),
+ afterToken, beforePreviousInsertions);
+ }
+ bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) {
+ return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after);
+ }
+ bool remove(SourceRange TokenRange) {
+ return remove(CharSourceRange::getTokenRange(TokenRange));
+ }
+ bool replace(SourceRange TokenRange, StringRef text) {
+ return replace(CharSourceRange::getTokenRange(TokenRange), text);
+ }
+ bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) {
+ return replaceWithInner(CharSourceRange::getTokenRange(TokenRange),
+ CharSourceRange::getTokenRange(TokenInnerRange));
+ }
+
+ typedef SmallVector<Edit, 8>::const_iterator edit_iterator;
+ edit_iterator edit_begin() const { return CachedEdits.begin(); }
+ edit_iterator edit_end() const { return CachedEdits.end(); }
+
+private:
+ void addInsert(SourceLocation OrigLoc,
+ FileOffset Offs, StringRef text, bool beforePreviousInsertions);
+ void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
+ FileOffset RangeOffs, unsigned RangeLen,
+ bool beforePreviousInsertions);
+ void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len);
+
+ bool canInsert(SourceLocation loc, FileOffset &Offset);
+ bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset,
+ SourceLocation &AfterLoc);
+ bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
+ bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len);
+ bool canReplaceText(SourceLocation loc, StringRef text,
+ FileOffset &Offs, unsigned &Len);
+
+ void commitInsert(FileOffset offset, StringRef text,
+ bool beforePreviousInsertions);
+ void commitRemove(FileOffset offset, unsigned length);
+
+ bool isAtStartOfMacroExpansion(SourceLocation loc,
+ SourceLocation *MacroBegin = 0) const;
+ bool isAtEndOfMacroExpansion(SourceLocation loc,
+ SourceLocation *MacroEnd = 0) const;
+};
+
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
new file mode 100644
index 0000000000..273921cee5
--- /dev/null
+++ b/include/clang/Edit/EditedSource.h
@@ -0,0 +1,87 @@
+//===----- EditedSource.h - Collection of source edits ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_EDITEDSOURCE_H
+#define LLVM_CLANG_EDIT_EDITEDSOURCE_H
+
+#include "clang/Edit/FileOffset.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <map>
+
+namespace clang {
+ class LangOptions;
+ class PreprocessingRecord;
+
+namespace edit {
+ class Commit;
+ class EditsReceiver;
+
+class EditedSource {
+ const SourceManager &SourceMgr;
+ const LangOptions &LangOpts;
+ const PreprocessingRecord *PPRec;
+
+ struct FileEdit {
+ StringRef Text;
+ unsigned RemoveLen;
+
+ FileEdit() : RemoveLen(0) {}
+ };
+
+ typedef std::map<FileOffset, FileEdit> FileEditsTy;
+ FileEditsTy FileEdits;
+
+ llvm::DenseMap<unsigned, SourceLocation> ExpansionToArgMap;
+
+ llvm::BumpPtrAllocator StrAlloc;
+
+public:
+ EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
+ const PreprocessingRecord *PPRec = 0)
+ : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec),
+ StrAlloc(/*size=*/512) { }
+
+ const SourceManager &getSourceManager() const { return SourceMgr; }
+ const LangOptions &getLangOptions() const { return LangOpts; }
+ const PreprocessingRecord *getPreprocessingRecord() const { return PPRec; }
+
+ bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
+
+ bool commit(const Commit &commit);
+
+ void applyRewrites(EditsReceiver &receiver);
+ void clearRewrites();
+
+ StringRef copyString(StringRef str) {
+ char *buf = StrAlloc.Allocate<char>(str.size());
+ std::uninitialized_copy(str.begin(), str.end(), buf);
+ return StringRef(buf, str.size());
+ }
+ StringRef copyString(const Twine &twine);
+
+private:
+ bool commitInsert(SourceLocation OrigLoc, FileOffset Offs, StringRef text,
+ bool beforePreviousInsertions);
+ bool commitInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
+ FileOffset InsertFromRangeOffs, unsigned Len,
+ bool beforePreviousInsertions);
+ void commitRemove(SourceLocation OrigLoc, FileOffset BeginOffs, unsigned Len);
+
+ StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs,
+ bool &Invalid);
+ FileEditsTy::iterator getActionForOffset(FileOffset Offs);
+};
+
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Edit/EditsReceiver.h b/include/clang/Edit/EditsReceiver.h
new file mode 100644
index 0000000000..600ac28ea9
--- /dev/null
+++ b/include/clang/Edit/EditsReceiver.h
@@ -0,0 +1,35 @@
+//===----- EditedSource.h - Collection of source edits ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_EDITSRECEIVER_H
+#define LLVM_CLANG_EDIT_EDITSRECEIVER_H
+
+#include "clang/Basic/LLVM.h"
+
+namespace clang {
+ class SourceLocation;
+ class CharSourceRange;
+
+namespace edit {
+
+class EditsReceiver {
+public:
+ virtual ~EditsReceiver() { }
+
+ virtual void insert(SourceLocation loc, StringRef text) = 0;
+ virtual void replace(CharSourceRange range, StringRef text) = 0;
+ /// \brief By default it calls replace with an empty string.
+ virtual void remove(CharSourceRange range);
+};
+
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Edit/FileOffset.h b/include/clang/Edit/FileOffset.h
new file mode 100644
index 0000000000..675ad18fcd
--- /dev/null
+++ b/include/clang/Edit/FileOffset.h
@@ -0,0 +1,65 @@
+//===----- FileOffset.h - Offset in a file ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_FILEOFFSET_H
+#define LLVM_CLANG_EDIT_FILEOFFSET_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+namespace edit {
+
+class FileOffset {
+ FileID FID;
+ unsigned Offs;
+public:
+ FileOffset() : Offs(0) { }
+ FileOffset(FileID fid, unsigned offs) : FID(fid), Offs(offs) { }
+
+ bool isInvalid() const { return FID.isInvalid(); }
+
+ FileID getFID() const { return FID; }
+ unsigned getOffset() const { return Offs; }
+
+ FileOffset getWithOffset(unsigned offset) const {
+ FileOffset NewOffs = *this;
+ NewOffs.Offs += offset;
+ return NewOffs;
+ }
+
+ friend bool operator==(FileOffset LHS, FileOffset RHS) {
+ return LHS.FID == RHS.FID && LHS.Offs == RHS.Offs;
+ }
+ friend bool operator!=(FileOffset LHS, FileOffset RHS) {
+ return !(LHS == RHS);
+ }
+ friend bool operator<(FileOffset LHS, FileOffset RHS) {
+ if (LHS.FID != RHS.FID)
+ return LHS.FID < RHS.FID;
+ return LHS.Offs < RHS.Offs;
+ }
+ friend bool operator>(FileOffset LHS, FileOffset RHS) {
+ if (LHS.FID != RHS.FID)
+ return LHS.FID > RHS.FID;
+ return LHS.Offs > RHS.Offs;
+ }
+ friend bool operator>=(FileOffset LHS, FileOffset RHS) {
+ return LHS > RHS || LHS == RHS;
+ }
+ friend bool operator<=(FileOffset LHS, FileOffset RHS) {
+ return LHS < RHS || LHS == RHS;
+ }
+};
+
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Edit/Rewriters.h b/include/clang/Edit/Rewriters.h
new file mode 100644
index 0000000000..aa7a5b2320
--- /dev/null
+++ b/include/clang/Edit/Rewriters.h
@@ -0,0 +1,33 @@
+//===--- Rewriters.h - Rewritings ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_REWRITERS_H
+#define LLVM_CLANG_EDIT_REWRITERS_H
+
+namespace clang {
+ class ObjCMessageExpr;
+ class NSAPI;
+
+namespace edit {
+ class Commit;
+
+bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg,
+ const NSAPI &NS, Commit &commit);
+
+bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
+ const NSAPI &NS, Commit &commit);
+
+bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg,
+ const NSAPI &NS, Commit &commit);
+
+}
+
+} // end namespace clang
+
+#endif