diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-01-10 18:50:15 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-01-10 18:50:15 +0000 |
commit | 9b1f44b147ff943729207be2b0509f6e53d62bbb (patch) | |
tree | 6ca8dcfc62f1ceafe5d55807c528aa3d94d9a279 /include | |
parent | b50df4a3df6db2ace3c011267934d3d10bdcc8db (diff) |
Add basic fix-its to SMDiagnostic.
Like Clang's FixItHint, SMFixIt represents an insertion, replacement, or
removal of source text. One or more fix-its can be emitted as part of
a diagnostic, and will be printed below the source range line to show the
user how they can fix their code.
Currently, the only client of SMFixIt is clang-tblgen; thus, the tests for
this behavior live in clang/test/TableGen/tg-fixits.td. If/when SMFixIt is
adopted within LLVM itself, those tests should be moved to the LLVM suite.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172086 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/Support/SourceMgr.h | 70 |
1 files changed, 59 insertions, 11 deletions
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index dddb013bf1..02abf92daa 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -17,6 +17,8 @@ #define LLVM_SUPPORT_SOURCEMGR_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/SMLoc.h" #include <string> @@ -24,6 +26,7 @@ namespace llvm { class MemoryBuffer; class SourceMgr; class SMDiagnostic; + class SMFixIt; class Twine; class raw_ostream; @@ -143,6 +146,7 @@ public: /// the default error handler is used. void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(), + ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>(), bool ShowColors = true) const; @@ -152,7 +156,8 @@ public: /// @param Msg If non-null, the kind of message (e.g., "error") which is /// prefixed to the message. SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, - ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const; + ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(), + ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>()) const; /// PrintIncludeStack - Prints the names of included files and the line of the /// file they were included from. A diagnostic handler can use this before @@ -164,6 +169,38 @@ public: }; +/// Represents a single fixit, a replacement of one range of text with another. +class SMFixIt { + SMRange Range; + + std::string Text; + +public: + // FIXME: Twine.str() is not very efficient. + SMFixIt(SMLoc Loc, const Twine &Insertion) + : Range(Loc, Loc), Text(Insertion.str()) { + assert(Loc.isValid()); + } + + // FIXME: Twine.str() is not very efficient. + SMFixIt(SMRange R, const Twine &Replacement) + : Range(R), Text(Replacement.str()) { + assert(R.isValid()); + } + + StringRef getText() const { return Text; } + SMRange getRange() const { return Range; } + + bool operator<(const SMFixIt &Other) const { + if (Range.Start.getPointer() != Other.Range.Start.getPointer()) + return Range.Start.getPointer() < Other.Range.Start.getPointer(); + if (Range.End.getPointer() != Other.Range.End.getPointer()) + return Range.End.getPointer() < Other.Range.End.getPointer(); + return Text < Other.Text; + } +}; + + /// SMDiagnostic - Instances of this class encapsulate one diagnostic report, /// allowing printing to a raw_ostream as a caret diagnostic. class SMDiagnostic { @@ -174,35 +211,46 @@ class SMDiagnostic { SourceMgr::DiagKind Kind; std::string Message, LineContents; std::vector<std::pair<unsigned, unsigned> > Ranges; + SmallVector<SMFixIt, 4> FixIts; public: // Null diagnostic. SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {} // Diagnostic with no location (e.g. file not found, command line arg error). - SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Knd, - const std::string &Msg) + SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg) : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), Message(Msg) {} // Diagnostic with a location. - SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN, + SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, int Col, SourceMgr::DiagKind Kind, - const std::string &Msg, const std::string &LineStr, - ArrayRef<std::pair<unsigned,unsigned> > Ranges); + StringRef Msg, StringRef LineStr, + ArrayRef<std::pair<unsigned,unsigned> > Ranges, + ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>()); const SourceMgr *getSourceMgr() const { return SM; } SMLoc getLoc() const { return Loc; } - const std::string &getFilename() const { return Filename; } + StringRef getFilename() const { return Filename; } int getLineNo() const { return LineNo; } int getColumnNo() const { return ColumnNo; } SourceMgr::DiagKind getKind() const { return Kind; } - const std::string &getMessage() const { return Message; } - const std::string &getLineContents() const { return LineContents; } - const std::vector<std::pair<unsigned, unsigned> > &getRanges() const { + StringRef getMessage() const { return Message; } + StringRef getLineContents() const { return LineContents; } + ArrayRef<std::pair<unsigned, unsigned> > getRanges() const { return Ranges; } - void print(const char *ProgName, raw_ostream &S, bool ShowColors = true) const; + + void addFixIt(const SMFixIt &Hint) { + FixIts.push_back(Hint); + } + + ArrayRef<SMFixIt> getFixIts() const { + return FixIts; + } + + void print(const char *ProgName, raw_ostream &S, + bool ShowColors = true) const; }; } // end llvm namespace |