summaryrefslogtreecommitdiff
path: root/lib/ASTMatchers/Dynamic/Diagnostics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ASTMatchers/Dynamic/Diagnostics.cpp')
-rw-r--r--lib/ASTMatchers/Dynamic/Diagnostics.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/lib/ASTMatchers/Dynamic/Diagnostics.cpp b/lib/ASTMatchers/Dynamic/Diagnostics.cpp
new file mode 100644
index 0000000000..fb3cac370f
--- /dev/null
+++ b/lib/ASTMatchers/Dynamic/Diagnostics.cpp
@@ -0,0 +1,113 @@
+//===--- Diagnostics.cpp - Helper class for error diagnostics -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+
+Diagnostics::ArgStream &
+Diagnostics::ArgStream::operator<<(const Twine &Arg) {
+ Out->push_back(Arg.str());
+ return *this;
+}
+
+Diagnostics::ArgStream Diagnostics::pushErrorFrame(const SourceRange &Range,
+ ErrorType Error) {
+ Frames.insert(Frames.begin(), ErrorFrame());
+ ErrorFrame &Last = Frames.front();
+ Last.Range = Range;
+ Last.Type = Error;
+ ArgStream Out = { &Last.Args };
+ return Out;
+}
+
+StringRef ErrorTypeToString(Diagnostics::ErrorType Type) {
+ switch (Type) {
+ case Diagnostics::ET_RegistryNotFound:
+ return "Matcher not found: $0";
+ case Diagnostics::ET_RegistryWrongArgCount:
+ return "Incorrect argument count. (Expected = $0) != (Actual = $1)";
+ case Diagnostics::ET_RegistryWrongArgType:
+ return "Incorrect type on function $0 for arg $1.";
+
+ case Diagnostics::ET_ParserStringError:
+ return "Error parsing string token: <$0>";
+ case Diagnostics::ET_ParserMatcherArgFailure:
+ return "Error parsing argument $0 for matcher $1.";
+ case Diagnostics::ET_ParserMatcherFailure:
+ return "Error building matcher $0.";
+ case Diagnostics::ET_ParserNoOpenParen:
+ return "Error parsing matcher. Found token <$0> while looking for '('.";
+ case Diagnostics::ET_ParserNoCloseParen:
+ return "Error parsing matcher. Found end-of-code while looking for ')'.";
+ case Diagnostics::ET_ParserNoComma:
+ return "Error parsing matcher. Found token <$0> while looking for ','.";
+ case Diagnostics::ET_ParserNoCode:
+ return "End of code found while looking for token.";
+ case Diagnostics::ET_ParserNotAMatcher:
+ return "Input value is not a matcher expression.";
+ case Diagnostics::ET_ParserInvalidToken:
+ return "Invalid token <$0> found when looking for a value.";
+
+ case Diagnostics::ET_None:
+ return "<N/A>";
+ }
+ llvm_unreachable("Unknown ErrorType value.");
+}
+
+std::string FormatErrorString(StringRef FormatString,
+ ArrayRef<std::string> Args) {
+ std::string Out;
+ while (!FormatString.empty()) {
+ std::pair<StringRef, StringRef> Pieces = FormatString.split("$");
+ Out += Pieces.first.str();
+ if (Pieces.second.empty()) break;
+
+ const char Next = Pieces.second.front();
+ FormatString = Pieces.second.drop_front();
+ if (Next >= '0' && Next <= '9') {
+ const unsigned Index = Next - '0';
+ if (Index < Args.size()) {
+ Out += Args[Index];
+ } else {
+ Out += "<Argument_Not_Provided>";
+ }
+ }
+ }
+ return Out;
+}
+
+std::string Diagnostics::ErrorFrame::ToString() const {
+ StringRef FormatString = ErrorTypeToString(Type);
+ std::string ErrorOut = FormatErrorString(FormatString, Args);
+ if (Range.Start.Line > 0 && Range.Start.Column > 0)
+ return (Twine(Range.Start.Line) + ":" + Twine(Range.Start.Column) + ": " +
+ ErrorOut).str();
+ return ErrorOut;
+}
+
+std::string Diagnostics::ToString() const {
+ if (Frames.empty()) return "";
+ return Frames[Frames.size() - 1].ToString();
+}
+
+std::string Diagnostics::ToStringFull() const {
+ std::string Result;
+ for (size_t i = 0, end = Frames.size(); i != end; ++i) {
+ if (i > 0) Result += "\n";
+ Result += Frames[i].ToString();
+ }
+ return Result;
+}
+
+} // namespace dynamic
+} // namespace ast_matchers
+} // namespace clang