summaryrefslogtreecommitdiff
path: root/clang/lib/Format/TokenAnalyzer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format/TokenAnalyzer.cpp')
-rw-r--r--clang/lib/Format/TokenAnalyzer.cpp49
1 files changed, 42 insertions, 7 deletions
diff --git a/clang/lib/Format/TokenAnalyzer.cpp b/clang/lib/Format/TokenAnalyzer.cpp
index f1459a808ff8..a619c6d939e9 100644
--- a/clang/lib/Format/TokenAnalyzer.cpp
+++ b/clang/lib/Format/TokenAnalyzer.cpp
@@ -26,26 +26,61 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Format/Format.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
+#include <type_traits>
#define DEBUG_TYPE "format-formatter"
namespace clang {
namespace format {
+// FIXME: Instead of printing the diagnostic we should store it and have a
+// better way to return errors through the format APIs.
+class FatalDiagnosticConsumer: public DiagnosticConsumer {
+public:
+ void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const Diagnostic &Info) override {
+ if (DiagLevel == DiagnosticsEngine::Fatal) {
+ Fatal = true;
+ llvm::SmallVector<char, 128> Message;
+ Info.FormatDiagnostic(Message);
+ llvm::errs() << Message << "\n";
+ }
+ }
+
+ bool fatalError() const { return Fatal; }
+
+private:
+ bool Fatal = false;
+};
+
+std::unique_ptr<Environment>
+Environment::make(StringRef Code, StringRef FileName,
+ ArrayRef<tooling::Range> Ranges, unsigned FirstStartColumn,
+ unsigned NextStartColumn, unsigned LastStartColumn) {
+ auto Env = std::make_unique<Environment>(Code, FileName, FirstStartColumn,
+ NextStartColumn, LastStartColumn);
+ FatalDiagnosticConsumer Diags;
+ Env->SM.getDiagnostics().setClient(&Diags, /*ShouldOwnClient=*/false);
+ SourceLocation StartOfFile = Env->SM.getLocForStartOfFile(Env->ID);
+ for (const tooling::Range &Range : Ranges) {
+ SourceLocation Start = StartOfFile.getLocWithOffset(Range.getOffset());
+ SourceLocation End = Start.getLocWithOffset(Range.getLength());
+ Env->CharRanges.push_back(CharSourceRange::getCharRange(Start, End));
+ }
+ // Validate that we can get the buffer data without a fatal error.
+ Env->SM.getBufferData(Env->ID);
+ if (Diags.fatalError()) return nullptr;
+ return Env;
+}
+
Environment::Environment(StringRef Code, StringRef FileName,
- ArrayRef<tooling::Range> Ranges,
unsigned FirstStartColumn, unsigned NextStartColumn,
unsigned LastStartColumn)
: VirtualSM(new SourceManagerForFile(FileName, Code)), SM(VirtualSM->get()),
ID(VirtualSM->get().getMainFileID()), FirstStartColumn(FirstStartColumn),
NextStartColumn(NextStartColumn), LastStartColumn(LastStartColumn) {
- SourceLocation StartOfFile = SM.getLocForStartOfFile(ID);
- for (const tooling::Range &Range : Ranges) {
- SourceLocation Start = StartOfFile.getLocWithOffset(Range.getOffset());
- SourceLocation End = Start.getLocWithOffset(Range.getLength());
- CharRanges.push_back(CharSourceRange::getCharRange(Start, End));
- }
}
TokenAnalyzer::TokenAnalyzer(const Environment &Env, const FormatStyle &Style)