From b837248ad46d12285c7166c9fb67db1604bdb1ad Mon Sep 17 00:00:00 2001 From: Samuel Benzaquen Date: Fri, 19 Jul 2013 20:02:35 +0000 Subject: [PATCH] Add support for raw_ostream on the printing methods of Diagnostics. Summary: Add printToStream*(llvm::raw_ostream&) methods to Diagnostics, and reimplement everything based on streams instead of concatenating strings. Also, fix some functions to start with lowercase to match the style guide. Reviewers: klimek CC: cfe-commits, revane Differential Revision: http://llvm-reviews.chandlerc.com/D1187 llvm-svn: 186715 --- .../clang/ASTMatchers/Dynamic/Diagnostics.h | 11 ++- clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp | 88 +++++++++++-------- .../ASTMatchers/Dynamic/ParserTest.cpp | 12 +-- .../ASTMatchers/Dynamic/RegistryTest.cpp | 14 +-- 4 files changed, 67 insertions(+), 58 deletions(-) diff --git a/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h index 49527e059e47..21292afec871 100644 --- a/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h +++ b/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h @@ -23,6 +23,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/raw_ostream.h" namespace clang { namespace ast_matchers { @@ -125,8 +126,6 @@ public: ContextType Type; SourceRange Range; std::vector Args; - - std::string ToString() const; }; /// \brief Information stored for each error found. @@ -135,20 +134,20 @@ public: SourceRange Range; ErrorType Type; std::vector Args; - - std::string ToString() const; }; ArrayRef errors() const { return Errors; } /// \brief Returns a simple string representation of each error. /// /// Each error only shows the error message without any context. - std::string ToString() const; + void printToStream(llvm::raw_ostream &OS) const; + std::string toString() const; /// \brief Returns the full string representation of each error. /// /// Each error message contains the full context. - std::string ToStringFull() const; + void printToStreamFull(llvm::raw_ostream &OS) const; + std::string toStringFull() const; private: /// \brief Helper function used by the constructors of ContextFrame. diff --git a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp index 71aeb9a75404..b72910e0ac4d 100644 --- a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp @@ -55,7 +55,7 @@ Diagnostics::ArgStream Diagnostics::addError(const SourceRange &Range, return ArgStream(&Last.Args); } -StringRef ContextTypeToString(Diagnostics::ContextType Type) { +StringRef contextTypeToFormatString(Diagnostics::ContextType Type) { switch (Type) { case Diagnostics::CT_MatcherConstruct: return "Error building matcher $0."; @@ -65,7 +65,7 @@ StringRef ContextTypeToString(Diagnostics::ContextType Type) { llvm_unreachable("Unknown ContextType value."); } -StringRef ErrorTypeToString(Diagnostics::ErrorType Type) { +StringRef errorTypeToFormatString(Diagnostics::ErrorType Type) { switch (Type) { case Diagnostics::ET_RegistryNotFound: return "Matcher not found: $0"; @@ -105,12 +105,11 @@ StringRef ErrorTypeToString(Diagnostics::ErrorType Type) { llvm_unreachable("Unknown ErrorType value."); } -std::string FormatErrorString(StringRef FormatString, - ArrayRef Args) { - std::string Out; +void formatErrorString(StringRef FormatString, ArrayRef Args, + llvm::raw_ostream &OS) { while (!FormatString.empty()) { std::pair Pieces = FormatString.split("$"); - Out += Pieces.first.str(); + OS << Pieces.first.str(); if (Pieces.second.empty()) break; const char Next = Pieces.second.front(); @@ -118,53 +117,64 @@ std::string FormatErrorString(StringRef FormatString, if (Next >= '0' && Next <= '9') { const unsigned Index = Next - '0'; if (Index < Args.size()) { - Out += Args[Index]; + OS << Args[Index]; } else { - Out += ""; + OS << ""; } } } - return Out; } -static std::string MaybeAddLineAndColumn(Twine Input, - const SourceRange &Range) { - if (Range.Start.Line > 0 && Range.Start.Column > 0) - return (Twine(Range.Start.Line) + ":" + Twine(Range.Start.Column) + ": " + - Input).str(); - return Input.str(); -} - -std::string Diagnostics::ContextFrame::ToString() const { - return MaybeAddLineAndColumn( - FormatErrorString(ContextTypeToString(Type), Args), Range); -} - -std::string Diagnostics::ErrorContent::ToString() const { - return MaybeAddLineAndColumn(FormatErrorString(ErrorTypeToString(Type), Args), - Range); -} - -std::string Diagnostics::ToString() const { - std::string Result; - for (size_t i = 0, e = Errors.size(); i != e; ++i) { - if (i != 0) Result += "\n"; - Result += Errors[i].ToString(); +static void maybeAddLineAndColumn(const SourceRange &Range, + llvm::raw_ostream &OS) { + if (Range.Start.Line > 0 && Range.Start.Column > 0) { + OS << Range.Start.Line << ":" << Range.Start.Column << ": "; } - return Result; } -std::string Diagnostics::ToStringFull() const { - std::string Result; +static void printContextFrameToStream(const Diagnostics::ContextFrame &Frame, + llvm::raw_ostream &OS) { + maybeAddLineAndColumn(Frame.Range, OS); + formatErrorString(contextTypeToFormatString(Frame.Type), Frame.Args, OS); +} + +static void printErrorContentToStream(const Diagnostics::ErrorContent &Content, + llvm::raw_ostream &OS) { + maybeAddLineAndColumn(Content.Range, OS); + formatErrorString(errorTypeToFormatString(Content.Type), Content.Args, OS); +} + +void Diagnostics::printToStream(llvm::raw_ostream &OS) const { for (size_t i = 0, e = Errors.size(); i != e; ++i) { - if (i != 0) Result += "\n"; + if (i != 0) OS << "\n"; + printErrorContentToStream(Errors[i], OS); + } +} + +std::string Diagnostics::toString() const { + std::string S; + llvm::raw_string_ostream OS(S); + printToStream(OS); + return OS.str(); +} + +void Diagnostics::printToStreamFull(llvm::raw_ostream &OS) const { + for (size_t i = 0, e = Errors.size(); i != e; ++i) { + if (i != 0) OS << "\n"; const ErrorContent &Error = Errors[i]; for (size_t i = 0, e = Error.ContextStack.size(); i != e; ++i) { - Result += Error.ContextStack[i].ToString() + "\n"; + printContextFrameToStream(Error.ContextStack[i], OS); + OS << "\n"; } - Result += Error.ToString(); + printErrorContentToStream(Error, OS); } - return Result; +} + +std::string Diagnostics::toStringFull() const { + std::string S; + llvm::raw_string_ostream OS(S); + printToStreamFull(OS); + return OS.str(); } } // namespace dynamic diff --git a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp index 6ef32dd47ac6..9ccd3dc04133 100644 --- a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp +++ b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp @@ -73,7 +73,7 @@ public: VariantValue Value; Parser::parseExpression(Code, this, &Value, &Error); Values.push_back(Value); - Errors.push_back(Error.ToStringFull()); + Errors.push_back(Error.toStringFull()); } MatcherList actOnMatcherExpression(StringRef MatcherName, @@ -184,7 +184,7 @@ TEST(ParserTest, FullParserTest) { "varDecl(hasInitializer(binaryOperator(hasLHS(integerLiteral())," " hasOperatorName(\"+\"))))", &Error)); - EXPECT_EQ("", Error.ToStringFull()); + EXPECT_EQ("", Error.toStringFull()); Matcher M = Matcher::constructFrom(*VarDecl); EXPECT_TRUE(matches("int x = 1 + false;", M)); EXPECT_FALSE(matches("int x = true + 1;", M)); @@ -193,7 +193,7 @@ TEST(ParserTest, FullParserTest) { OwningPtr HasParameter(Parser::parseMatcherExpression( "functionDecl(hasParameter(1, hasName(\"x\")))", &Error)); - EXPECT_EQ("", Error.ToStringFull()); + EXPECT_EQ("", Error.toStringFull()); M = Matcher::constructFrom(*HasParameter); EXPECT_TRUE(matches("void f(int a, int x);", M)); @@ -206,20 +206,20 @@ TEST(ParserTest, FullParserTest) { "2:20: Error building matcher hasLHS.\n" "2:27: Incorrect type for arg 1. " "(Expected = Matcher) != (Actual = String)", - Error.ToStringFull()); + Error.toStringFull()); } std::string ParseWithError(StringRef Code) { Diagnostics Error; VariantValue Value; Parser::parseExpression(Code, &Value, &Error); - return Error.ToStringFull(); + return Error.toStringFull(); } std::string ParseMatcherWithError(StringRef Code) { Diagnostics Error; Parser::parseMatcherExpression(Code, &Error); - return Error.ToStringFull(); + return Error.toStringFull(); } TEST(ParserTest, Errors) { diff --git a/clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp index d546fe59ff95..178a64a9fbf1 100644 --- a/clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp +++ b/clang/unittests/ASTMatchers/Dynamic/RegistryTest.cpp @@ -42,7 +42,7 @@ public: if (!Error) Error = &DummyError; const MatcherList Out = Registry::constructMatcher(MatcherName, SourceRange(), Args(), Error); - EXPECT_EQ("", DummyError.ToStringFull()); + EXPECT_EQ("", DummyError.toStringFull()); return Out; } @@ -52,7 +52,7 @@ public: if (!Error) Error = &DummyError; const MatcherList Out = Registry::constructMatcher( MatcherName, SourceRange(), Args(Arg1), Error); - EXPECT_EQ("", DummyError.ToStringFull()); + EXPECT_EQ("", DummyError.toStringFull()); return Out; } @@ -63,7 +63,7 @@ public: if (!Error) Error = &DummyError; const MatcherList Out = Registry::constructMatcher( MatcherName, SourceRange(), Args(Arg1, Arg2), Error); - EXPECT_EQ("", DummyError.ToStringFull()); + EXPECT_EQ("", DummyError.toStringFull()); return Out; } }; @@ -203,24 +203,24 @@ TEST_F(RegistryTest, Errors) { OwningPtr Error(new Diagnostics()); EXPECT_TRUE(constructMatcher("hasInitializer", Error.get()).empty()); EXPECT_EQ("Incorrect argument count. (Expected = 1) != (Actual = 0)", - Error->ToString()); + Error->toString()); Error.reset(new Diagnostics()); EXPECT_TRUE(constructMatcher("isArrow", std::string(), Error.get()).empty()); EXPECT_EQ("Incorrect argument count. (Expected = 0) != (Actual = 1)", - Error->ToString()); + Error->toString()); // Bad argument type Error.reset(new Diagnostics()); EXPECT_TRUE(constructMatcher("ofClass", std::string(), Error.get()).empty()); EXPECT_EQ("Incorrect type for arg 1. (Expected = Matcher) != " "(Actual = String)", - Error->ToString()); + Error->toString()); Error.reset(new Diagnostics()); EXPECT_TRUE(constructMatcher("recordDecl", recordDecl(), parameterCountIs(3), Error.get()).empty()); EXPECT_EQ("Incorrect type for arg 2. (Expected = Matcher) != " "(Actual = Matcher)", - Error->ToString()); + Error->toString()); } } // end anonymous namespace