blob: 79c9389cf5fedde28f64ec808a6361fd96a47d55 [file] [log] [blame]
Manuel Klimekf7f295f2013-05-14 09:13:00 +00001//===--- Diagnostics.cpp - Helper class for error diagnostics -----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
11
12namespace clang {
13namespace ast_matchers {
14namespace dynamic {
15
16Diagnostics::ArgStream &
17Diagnostics::ArgStream::operator<<(const Twine &Arg) {
18 Out->push_back(Arg.str());
19 return *this;
20}
21
22Diagnostics::ArgStream Diagnostics::pushErrorFrame(const SourceRange &Range,
23 ErrorType Error) {
24 Frames.insert(Frames.begin(), ErrorFrame());
25 ErrorFrame &Last = Frames.front();
26 Last.Range = Range;
27 Last.Type = Error;
28 ArgStream Out = { &Last.Args };
29 return Out;
30}
31
32StringRef ErrorTypeToString(Diagnostics::ErrorType Type) {
33 switch (Type) {
34 case Diagnostics::ET_RegistryNotFound:
35 return "Matcher not found: $0";
36 case Diagnostics::ET_RegistryWrongArgCount:
37 return "Incorrect argument count. (Expected = $0) != (Actual = $1)";
38 case Diagnostics::ET_RegistryWrongArgType:
39 return "Incorrect type on function $0 for arg $1.";
Samuel Benzaquen4f37d922013-06-03 19:31:08 +000040 case Diagnostics::ET_RegistryNotBindable:
41 return "Matcher does not support binding.";
Manuel Klimekf7f295f2013-05-14 09:13:00 +000042
43 case Diagnostics::ET_ParserStringError:
44 return "Error parsing string token: <$0>";
45 case Diagnostics::ET_ParserMatcherArgFailure:
46 return "Error parsing argument $0 for matcher $1.";
47 case Diagnostics::ET_ParserMatcherFailure:
48 return "Error building matcher $0.";
49 case Diagnostics::ET_ParserNoOpenParen:
50 return "Error parsing matcher. Found token <$0> while looking for '('.";
51 case Diagnostics::ET_ParserNoCloseParen:
52 return "Error parsing matcher. Found end-of-code while looking for ')'.";
53 case Diagnostics::ET_ParserNoComma:
54 return "Error parsing matcher. Found token <$0> while looking for ','.";
55 case Diagnostics::ET_ParserNoCode:
56 return "End of code found while looking for token.";
57 case Diagnostics::ET_ParserNotAMatcher:
58 return "Input value is not a matcher expression.";
59 case Diagnostics::ET_ParserInvalidToken:
60 return "Invalid token <$0> found when looking for a value.";
Samuel Benzaquen4f37d922013-06-03 19:31:08 +000061 case Diagnostics::ET_ParserMalformedBindExpr:
62 return "Malformed bind() expression.";
63 case Diagnostics::ET_ParserTrailingCode:
64 return "Expected end of code.";
Samuel Benzaquen7a337af2013-06-04 15:46:22 +000065 case Diagnostics::ET_ParserUnsignedError:
66 return "Error parsing unsigned token: <$0>";
Manuel Klimekf7f295f2013-05-14 09:13:00 +000067
68 case Diagnostics::ET_None:
69 return "<N/A>";
70 }
71 llvm_unreachable("Unknown ErrorType value.");
72}
73
74std::string FormatErrorString(StringRef FormatString,
75 ArrayRef<std::string> Args) {
76 std::string Out;
77 while (!FormatString.empty()) {
78 std::pair<StringRef, StringRef> Pieces = FormatString.split("$");
79 Out += Pieces.first.str();
80 if (Pieces.second.empty()) break;
81
82 const char Next = Pieces.second.front();
83 FormatString = Pieces.second.drop_front();
84 if (Next >= '0' && Next <= '9') {
85 const unsigned Index = Next - '0';
86 if (Index < Args.size()) {
87 Out += Args[Index];
88 } else {
89 Out += "<Argument_Not_Provided>";
90 }
91 }
92 }
93 return Out;
94}
95
96std::string Diagnostics::ErrorFrame::ToString() const {
97 StringRef FormatString = ErrorTypeToString(Type);
98 std::string ErrorOut = FormatErrorString(FormatString, Args);
99 if (Range.Start.Line > 0 && Range.Start.Column > 0)
100 return (Twine(Range.Start.Line) + ":" + Twine(Range.Start.Column) + ": " +
101 ErrorOut).str();
102 return ErrorOut;
103}
104
105std::string Diagnostics::ToString() const {
106 if (Frames.empty()) return "";
107 return Frames[Frames.size() - 1].ToString();
108}
109
110std::string Diagnostics::ToStringFull() const {
111 std::string Result;
112 for (size_t i = 0, end = Frames.size(); i != end; ++i) {
113 if (i > 0) Result += "\n";
114 Result += Frames[i].ToString();
115 }
116 return Result;
117}
118
119} // namespace dynamic
120} // namespace ast_matchers
121} // namespace clang