summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/DiagnosticRenderer.cpp
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
commitf7639e1b4a6c8cbf69c0005c6173ac863735b572 (patch)
treeec10ddb85eb9803b67b1053bcac26e0050810ff3 /clang/lib/Frontend/DiagnosticRenderer.cpp
parentd151dde0e6673a15e9bf0b5f328df461dfd8cae9 (diff)
downloadbcm5719-llvm-f7639e1b4a6c8cbf69c0005c6173ac863735b572.tar.gz
bcm5719-llvm-f7639e1b4a6c8cbf69c0005c6173ac863735b572.zip
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. llvm-svn: 152141
Diffstat (limited to 'clang/lib/Frontend/DiagnosticRenderer.cpp')
-rw-r--r--clang/lib/Frontend/DiagnosticRenderer.cpp57
1 files changed, 57 insertions, 0 deletions
diff --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp
index 29f9ed5a7d4..6c3bb1d6953 100644
--- a/clang/lib/Frontend/DiagnosticRenderer.cpp
+++ b/clang/lib/Frontend/DiagnosticRenderer.cpp
@@ -12,6 +12,9 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Lex/Lexer.h"
+#include "clang/Edit/EditedSource.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/EditsReceiver.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
@@ -127,6 +130,54 @@ DiagnosticRenderer::DiagnosticRenderer(const SourceManager &SM,
DiagnosticRenderer::~DiagnosticRenderer() {}
+namespace {
+
+class FixitReceiver : public edit::EditsReceiver {
+ SmallVectorImpl<FixItHint> &MergedFixits;
+
+public:
+ FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits)
+ : MergedFixits(MergedFixits) { }
+ virtual void insert(SourceLocation loc, StringRef text) {
+ MergedFixits.push_back(FixItHint::CreateInsertion(loc, text));
+ }
+ virtual void replace(CharSourceRange range, StringRef text) {
+ MergedFixits.push_back(FixItHint::CreateReplacement(range, text));
+ }
+};
+
+}
+
+static void mergeFixits(ArrayRef<FixItHint> FixItHints,
+ const SourceManager &SM, const LangOptions &LangOpts,
+ SmallVectorImpl<FixItHint> &MergedFixits) {
+ edit::Commit commit(SM, LangOpts);
+ for (ArrayRef<FixItHint>::const_iterator
+ I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) {
+ const FixItHint &Hint = *I;
+ if (Hint.CodeToInsert.empty()) {
+ if (Hint.InsertFromRange.isValid())
+ commit.insertFromRange(Hint.RemoveRange.getBegin(),
+ Hint.InsertFromRange, /*afterToken=*/false,
+ Hint.BeforePreviousInsertions);
+ else
+ commit.remove(Hint.RemoveRange);
+ } else {
+ if (Hint.RemoveRange.isTokenRange() ||
+ Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd())
+ commit.replace(Hint.RemoveRange, Hint.CodeToInsert);
+ else
+ commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert,
+ /*afterToken=*/false, Hint.BeforePreviousInsertions);
+ }
+ }
+
+ edit::EditedSource Editor(SM, LangOpts);
+ if (Editor.commit(commit)) {
+ FixitReceiver Rec(MergedFixits);
+ Editor.applyRewrites(Rec);
+ }
+}
void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
DiagnosticsEngine::Level Level,
@@ -152,6 +203,12 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(),
Ranges.end());
+ llvm::SmallVector<FixItHint, 8> MergedFixits;
+ if (!FixItHints.empty()) {
+ mergeFixits(FixItHints, SM, LangOpts, MergedFixits);
+ FixItHints = MergedFixits;
+ }
+
for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(),
E = FixItHints.end();
I != E; ++I)
OpenPOWER on IntegriCloud