forked from OSchip/llvm-project
114 lines
3.6 KiB
C++
114 lines
3.6 KiB
C++
//===--- 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
|