aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--include/clang-c/Index.h14
-rw-r--r--include/clang/ARCMigrate/ARCMT.h9
-rw-r--r--include/clang/ARCMigrate/ARCMTActions.h26
-rw-r--r--include/clang/ARCMigrate/FileRemapper.h9
-rw-r--r--include/clang/Basic/Diagnostic.h25
-rw-r--r--include/clang/Driver/Action.h12
-rw-r--r--include/clang/Driver/CC1Options.td11
-rw-r--r--include/clang/Driver/Options.td12
-rw-r--r--include/clang/Driver/Types.def1
-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
-rw-r--r--include/clang/Frontend/FrontendOptions.h13
-rw-r--r--include/clang/Rewrite/FixItRewriter.h3
-rw-r--r--lib/ARCMigrate/ARCMT.cpp46
-rw-r--r--lib/ARCMigrate/CMakeLists.txt1
-rw-r--r--lib/ARCMigrate/FileRemapper.cpp26
-rw-r--r--lib/ARCMigrate/ObjCMT.cpp226
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp94
-rw-r--r--lib/Basic/DiagnosticIDs.cpp13
-rw-r--r--lib/CMakeLists.txt1
-rw-r--r--lib/Driver/Action.cpp7
-rw-r--r--lib/Driver/Driver.cpp3
-rw-r--r--lib/Driver/ToolChain.cpp2
-rw-r--r--lib/Driver/ToolChains.cpp2
-rw-r--r--lib/Driver/Tools.cpp25
-rw-r--r--lib/Driver/WindowsToolChain.cpp1
-rw-r--r--lib/Edit/CMakeLists.txt7
-rw-r--r--lib/Edit/Commit.cpp345
-rw-r--r--lib/Edit/EditedSource.cpp329
-rw-r--r--lib/Edit/Makefile14
-rw-r--r--lib/Edit/RewriteObjCFoundationAPI.cpp589
-rw-r--r--lib/Frontend/CompilerInvocation.cpp31
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp57
-rw-r--r--lib/FrontendTool/ExecuteCompilerInvocation.cpp9
-rwxr-xr-xlib/Makefile2
-rw-r--r--lib/Rewrite/FixItRewriter.cpp69
-rw-r--r--test/ARCMT/dispatch.m29
-rw-r--r--test/ARCMT/dispatch.m.result25
-rw-r--r--test/ARCMT/driver-migrate.m2
-rw-r--r--test/ARCMT/migrate-emit-errors.m2
-rw-r--r--test/ARCMT/migrate-plist-output.m2
-rw-r--r--test/ARCMT/migrate-space-in-path.m6
-rw-r--r--test/ARCMT/migrate.m6
-rw-r--r--test/ARCMT/objcmt-numeric-literals.m501
-rw-r--r--test/ARCMT/objcmt-numeric-literals.m.result501
-rw-r--r--test/ARCMT/objcmt-subscripting-literals.m137
-rw-r--r--test/ARCMT/objcmt-subscripting-literals.m.result137
-rw-r--r--test/ARCMT/with-arc-mode-migrate.m4
-rw-r--r--test/ARCMT/with-arc-mode-migrate.m.result4
-rw-r--r--tools/arcmt-test/CMakeLists.txt1
-rw-r--r--tools/arcmt-test/Makefile2
-rw-r--r--tools/arcmt-test/arcmt-test.cpp5
-rw-r--r--tools/c-arcmt-test/c-arcmt-test.c33
-rw-r--r--tools/driver/CMakeLists.txt2
-rw-r--r--tools/driver/Makefile2
-rw-r--r--tools/libclang/ARCMigrate.cpp41
-rw-r--r--tools/libclang/CMakeLists.txt1
-rw-r--r--tools/libclang/Makefile3
-rw-r--r--tools/libclang/libclang.exports1
-rw-r--r--unittests/Frontend/Makefile2
-rw-r--r--unittests/Lex/LexerTest.cpp4
64 files changed, 3748 insertions, 99 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 746490be88..fd7a9f3a01 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -3983,6 +3983,20 @@ typedef void *CXRemapping;
CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *path);
/**
+ * \brief Retrieve a remapping.
+ *
+ * \param filePaths pointer to an array of file paths containing remapping info.
+ *
+ * \param numFiles number of file paths.
+ *
+ * \returns the requested remapping. This remapping must be freed
+ * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred.
+ */
+CINDEX_LINKAGE
+CXRemapping clang_getRemappingsFromFileList(const char **filePaths,
+ unsigned numFiles);
+
+/**
* \brief Determine the number of remappings.
*/
CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping);
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
index 738a00dcd0..86a6cbb22a 100644
--- a/include/clang/ARCMigrate/ARCMT.h
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -76,6 +76,15 @@ bool getFileRemappings(std::vector<std::pair<std::string,std::string> > &remap,
StringRef outputDir,
DiagnosticConsumer *DiagClient);
+/// \brief Get the set of file remappings from a list of files with remapping
+/// info.
+///
+/// \returns false if no error is produced, true otherwise.
+bool getFileRemappingsFromFileList(
+ std::vector<std::pair<std::string,std::string> > &remap,
+ ArrayRef<StringRef> remapFiles,
+ DiagnosticConsumer *DiagClient);
+
typedef void (*TransformFn)(MigrationPass &pass);
std::vector<TransformFn> getAllTransformations(LangOptions::GCMode OrigGCMode,
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
index 4eac4facdd..e075252137 100644
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -11,6 +11,7 @@
#define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
#include "clang/Frontend/FrontendAction.h"
+#include "clang/ARCMigrate/FileRemapper.h"
#include "llvm/ADT/OwningPtr.h"
namespace clang {
@@ -32,6 +33,14 @@ public:
ModifyAction(FrontendAction *WrappedAction);
};
+class MigrateSourceAction : public ASTFrontendAction {
+ FileRemapper Remapper;
+protected:
+ virtual bool BeginInvocation(CompilerInstance &CI);
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile);
+};
+
class MigrateAction : public WrapperFrontendAction {
std::string MigrateDir;
std::string PlistOut;
@@ -45,6 +54,23 @@ public:
bool emitPremigrationARCErrors);
};
+/// \brief Migrates to modern ObjC syntax.
+class ObjCMigrateAction : public WrapperFrontendAction {
+ std::string MigrateDir;
+ bool MigrateLiterals;
+ bool MigrateSubscripting;
+ FileRemapper Remapper;
+ CompilerInstance *CompInst;
+public:
+ ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
+ bool migrateLiterals,
+ bool migrateSubscripting);
+
+protected:
+ virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile);
+ virtual bool BeginInvocation(CompilerInstance &CI);
+};
+
}
}
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
index a451988f93..fe7cfadb49 100644
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -24,7 +24,7 @@ namespace clang {
class FileManager;
class FileEntry;
class DiagnosticsEngine;
- class CompilerInvocation;
+ class PreprocessorOptions;
namespace arcmt {
@@ -44,7 +44,10 @@ public:
bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag,
bool ignoreIfFilesChanged);
+ bool initFromFile(StringRef filePath, DiagnosticsEngine &Diag,
+ bool ignoreIfFilesChanged);
bool flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag);
+ bool flushToFile(StringRef outputPath, DiagnosticsEngine &Diag);
bool overwriteOriginal(DiagnosticsEngine &Diag,
StringRef outputDir = StringRef());
@@ -52,9 +55,9 @@ public:
void remap(StringRef filePath, llvm::MemoryBuffer *memBuf);
void remap(StringRef filePath, StringRef newPath);
- void applyMappings(CompilerInvocation &CI) const;
+ void applyMappings(PreprocessorOptions &PPOpts) const;
- void transferMappingsAndClear(CompilerInvocation &CI);
+ void transferMappingsAndClear(PreprocessorOptions &PPOpts);
void clear(StringRef outputDir = StringRef());
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 3e54b4352b..2b71d445cc 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -50,13 +50,19 @@ public:
/// insertion hint.
CharSourceRange RemoveRange;
+ /// \brief Code in the specific range that should be inserted in the insertion
+ /// location.
+ CharSourceRange InsertFromRange;
+
/// \brief The actual code to insert at the insertion location, as a
/// string.
std::string CodeToInsert;
+ bool BeforePreviousInsertions;
+
/// \brief Empty code modification hint, indicating that no code
/// modification is known.
- FixItHint() : RemoveRange() { }
+ FixItHint() : BeforePreviousInsertions(false) { }
bool isNull() const {
return !RemoveRange.isValid();
@@ -65,11 +71,26 @@ public:
/// \brief Create a code modification hint that inserts the given
/// code string at a specific location.
static FixItHint CreateInsertion(SourceLocation InsertionLoc,
- StringRef Code) {
+ StringRef Code,
+ bool BeforePreviousInsertions = false) {
FixItHint Hint;
Hint.RemoveRange =
CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
Hint.CodeToInsert = Code;
+ Hint.BeforePreviousInsertions = BeforePreviousInsertions;
+ return Hint;
+ }
+
+ /// \brief Create a code modification hint that inserts the given
+ /// code from \arg FromRange at a specific location.
+ static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
+ CharSourceRange FromRange,
+ bool BeforePreviousInsertions = false) {
+ FixItHint Hint;
+ Hint.RemoveRange =
+ CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
+ Hint.InsertFromRange = FromRange;
+ Hint.BeforePreviousInsertions = BeforePreviousInsertions;
return Hint;
}
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index 41ce4d92c4..6e317a0726 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -39,6 +39,7 @@ public:
PreprocessJobClass,
PrecompileJobClass,
AnalyzeJobClass,
+ MigrateJobClass,
CompileJobClass,
AssembleJobClass,
LinkJobClass,
@@ -171,6 +172,17 @@ public:
static bool classof(const AnalyzeJobAction *) { return true; }
};
+class MigrateJobAction : public JobAction {
+ virtual void anchor();
+public:
+ MigrateJobAction(Action *Input, types::ID OutputType);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == MigrateJobClass;
+ }
+ static bool classof(const MigrateJobAction *) { return true; }
+};
+
class CompileJobAction : public JobAction {
virtual void anchor();
public:
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 93e63dee61..2fe4eba205 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -433,21 +433,28 @@ def rewrite_objc : Flag<"-rewrite-objc">,
HelpText<"Rewrite ObjC into C (code rewriter example)">;
def rewrite_macros : Flag<"-rewrite-macros">,
HelpText<"Expand macros without full preprocessing">;
+def migrate : Flag<"-migrate">,
+ HelpText<"Migrate source code">;
}
+def mt_migrate_directory : Separate<"-mt-migrate-directory">,
+ HelpText<"Directory for temporary files produced during ARC or ObjC migration">;
def arcmt_check : Flag<"-arcmt-check">,
HelpText<"Check for ARC migration issues that need manual handling">;
def arcmt_modify : Flag<"-arcmt-modify">,
HelpText<"Apply modifications to files to conform to ARC">;
def arcmt_migrate : Flag<"-arcmt-migrate">,
HelpText<"Apply modifications and produces temporary files that conform to ARC">;
-def arcmt_migrate_directory : Separate<"-arcmt-migrate-directory">,
- HelpText<"Directory for temporary files produced during ARC migration">;
def arcmt_migrate_report_output : Separate<"-arcmt-migrate-report-output">,
HelpText<"Output path for the plist report">;
def arcmt_migrate_emit_arc_errors : Flag<"-arcmt-migrate-emit-errors">,
HelpText<"Emit ARC errors even if the migrator can fix them">;
+def objcmt_migrate_literals : Flag<"-objcmt-migrate-literals">,
+ HelpText<"Enable migration to modern ObjC literals">;
+def objcmt_migrate_subscripting : Flag<"-objcmt-migrate-subscripting">,
+ HelpText<"Enable migration to modern ObjC subscripting">;
+
def working_directory : JoinedOrSeparate<"-working-directory">,
HelpText<"Resolve file paths relative to the specified directory">;
def working_directory_EQ : Joined<"-working-directory=">,
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index b269ddb045..51c5e020e1 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -118,13 +118,21 @@ def ccc_arrmt_check : Flag<"-ccc-arrmt-check">, Alias<ccc_arcmt_check>;
def ccc_arrmt_modify : Flag<"-ccc-arrmt-modify">, Alias<ccc_arcmt_modify>;
def ccc_arcmt_migrate : Separate<"-ccc-arcmt-migrate">, CCCDriverOpt,
HelpText<"Apply modifications and produces temporary files that conform to ARC">;
-def ccc_arcmt_migrate_EQ : Joined<"-ccc-arcmt-migrate=">, CCCDriverOpt,
- Alias<ccc_arcmt_migrate>;
def arcmt_migrate_report_output : Separate<"-arcmt-migrate-report-output">,
HelpText<"Output path for the plist report">;
def arcmt_migrate_emit_arc_errors : Flag<"-arcmt-migrate-emit-errors">,
HelpText<"Emit ARC errors even if the migrator can fix them">;
+def _migrate : Flag<"--migrate">, Flags<[DriverOption]>,
+ HelpText<"Run the migrator">;
+def ccc_objcmt_migrate : Separate<"-ccc-objcmt-migrate">, CCCDriverOpt,
+ HelpText<"Apply modifications and produces temporary files to migrate to "
+ "modern ObjC syntax">;
+def objcmt_migrate_literals : Flag<"-objcmt-migrate-literals">,
+ HelpText<"Enable migration to modern ObjC literals">;
+def objcmt_migrate_subscripting : Flag<"-objcmt-migrate-subscripting">,
+ HelpText<"Enable migration to modern ObjC subscripting">;
+
// Make sure all other -ccc- options are rejected.
def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>;
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index 8449d639e6..bba888ca4a 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -82,6 +82,7 @@ TYPE("lto-bc", LTO_BC, INVALID, "o", "")
TYPE("ast", AST, INVALID, "ast", "u")
TYPE("plist", Plist, INVALID, "plist", "")
TYPE("rewritten-objc", RewrittenObjC,INVALID, "cpp", "")
+TYPE("remap", Remap, INVALID, "remap", "")
TYPE("precompiled-header", PCH, INVALID, "gch", "A")
TYPE("object", Object, INVALID, "o", "")
TYPE("treelang", Treelang, INVALID, 0, "u")
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"
+#includ