<div dir="ltr">Thanks for the report.<div>Will send a fix shortly.</div><div>_Sam<br><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Apr 23, 2014 at 11:45 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Apr 23, 2014 at 10:04 AM, Samuel Benzaquen <<a href="mailto:sbenza@google.com">sbenza@google.com</a>> wrote:<br>
> Author: sbenza<br>
> Date: Wed Apr 23 09:04:52 2014<br>
> New Revision: 206984<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=206984&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=206984&view=rev</a><br>
> Log:<br>
> Add new 'let' command to bind arbitrary values into constants.<br>
><br>
> Summary:<br>
> Add new 'let' command to bind arbitrary values into constants.<br>
> These constants can then be used in the matcher expressions.<br>
><br>
> Reviewers: pcc<br>
><br>
> CC: cfe-commits<br>
><br>
> Differential Revision: <a href="http://reviews.llvm.org/D3383" target="_blank">http://reviews.llvm.org/D3383</a><br>
><br>
> Modified:<br>
> clang-tools-extra/trunk/clang-query/Query.cpp<br>
> clang-tools-extra/trunk/clang-query/Query.h<br>
> clang-tools-extra/trunk/clang-query/QueryParser.cpp<br>
> clang-tools-extra/trunk/clang-query/QueryParser.h<br>
> clang-tools-extra/trunk/clang-query/QuerySession.h<br>
> clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp<br>
> clang-tools-extra/trunk/unittests/clang-query/QueryEngineTest.cpp<br>
> clang-tools-extra/trunk/unittests/clang-query/QueryParserTest.cpp<br>
><br>
> Modified: clang-tools-extra/trunk/clang-query/Query.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/Query.cpp?rev=206984&r1=206983&r2=206984&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/Query.cpp?rev=206984&r1=206983&r2=206984&view=diff</a><br>
> ==============================================================================<br>
> --- clang-tools-extra/trunk/clang-query/Query.cpp (original)<br>
> +++ clang-tools-extra/trunk/clang-query/Query.cpp Wed Apr 23 09:04:52 2014<br>
> @@ -54,7 +54,7 @@ struct CollectBoundNodes : MatchFinder::<br>
> }<br>
> };<br>
><br>
> -}<br>
> +} // namespace<br>
><br>
> bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {<br>
> unsigned MatchCount = 0;<br>
> @@ -124,6 +124,15 @@ bool MatchQuery::run(llvm::raw_ostream &<br>
> return true;<br>
> }<br>
><br>
> +bool LetQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {<br>
> + if (Value) {<br>
> + QS.NamedValues[Name] = Value;<br>
> + } else {<br>
> + QS.NamedValues.erase(Name);<br>
> + }<br>
> + return true;<br>
> +}<br>
> +<br>
> #ifndef _MSC_VER<br>
> const QueryKind SetQueryKind<bool>::value;<br>
> const QueryKind SetQueryKind<OutputKind>::value;<br>
><br>
> Modified: clang-tools-extra/trunk/clang-query/Query.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/Query.h?rev=206984&r1=206983&r2=206984&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/Query.h?rev=206984&r1=206983&r2=206984&view=diff</a><br>
> ==============================================================================<br>
> --- clang-tools-extra/trunk/clang-query/Query.h (original)<br>
> +++ clang-tools-extra/trunk/clang-query/Query.h Wed Apr 23 09:04:52 2014<br>
> @@ -28,9 +28,10 @@ enum QueryKind {<br>
> QK_Invalid,<br>
> QK_NoOp,<br>
> QK_Help,<br>
> + QK_Let,<br>
> QK_Match,<br>
> QK_SetBool,<br>
> - QK_SetOutputKind<br>
> + QK_SetOutputKind,<br>
> };<br>
><br>
> class QuerySession;<br>
> @@ -86,6 +87,17 @@ struct MatchQuery : Query {<br>
> static bool classof(const Query *Q) { return Q->Kind == QK_Match; }<br>
> };<br>
><br>
> +struct LetQuery : Query {<br>
> + LetQuery(StringRef Name, const ast_matchers::dynamic::VariantValue &Value)<br>
> + : Query(QK_Let), Name(Name), Value(Value) {}<br>
> + bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;<br>
> +<br>
> + std::string Name;<br>
> + ast_matchers::dynamic::VariantValue Value;<br>
> +<br>
> + static bool classof(const Query *Q) { return Q->Kind == QK_Let; }<br>
> +};<br>
> +<br>
> template <typename T> struct SetQueryKind {};<br>
><br>
> template <> struct SetQueryKind<bool> {<br>
><br>
> Modified: clang-tools-extra/trunk/clang-query/QueryParser.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/QueryParser.cpp?rev=206984&r1=206983&r2=206984&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/QueryParser.cpp?rev=206984&r1=206983&r2=206984&view=diff</a><br>
> ==============================================================================<br>
> --- clang-tools-extra/trunk/clang-query/QueryParser.cpp (original)<br>
> +++ clang-tools-extra/trunk/clang-query/QueryParser.cpp Wed Apr 23 09:04:52 2014<br>
> @@ -132,12 +132,16 @@ QueryRef QueryParser::endQuery(QueryRef<br>
> return Q;<br>
> }<br>
><br>
> +namespace {<br>
> +<br>
> enum ParsedQueryKind {<br>
> PQK_Invalid,<br>
> PQK_NoOp,<br>
> PQK_Help,<br>
> + PQK_Let,<br>
> PQK_Match,<br>
> - PQK_Set<br>
> + PQK_Set,<br>
> + PQK_Unlet,<br>
> };<br>
><br>
> enum ParsedQueryVariable {<br>
> @@ -146,16 +150,52 @@ enum ParsedQueryVariable {<br>
> PQV_BindRoot<br>
> };<br>
><br>
> +QueryRef makeInvalidQueryFromDiagnostics(const Diagnostics &Diag) {<br>
> + std::string ErrStr;<br>
> + llvm::raw_string_ostream OS(ErrStr);<br>
> + Diag.printToStreamFull(OS);<br>
> + return new InvalidQuery(OS.str());<br>
> +}<br>
> +<br>
> +class QuerySessionSema : public Parser::RegistrySema {<br>
> +public:<br>
> + QuerySessionSema(const QuerySession &QS) : QS(QS) {}<br>
> +<br>
> + ast_matchers::dynamic::VariantValue getNamedValue(StringRef Name) override {<br>
> + return QS.NamedValues.lookup(Name);<br>
> + }<br>
> +<br>
> +private:<br>
> + const QuerySession &QS;<br>
> +};<br>
> +<br>
> +} // namespace<br>
> +<br>
> +QueryRef QueryParser::completeMatcherExpression() {<br>
> + std::vector<MatcherCompletion> Comps = Parser::completeExpression(<br>
> + StringRef(Begin, End - Begin), CompletionPos - Begin);<br>
> + for (std::vector<MatcherCompletion>::iterator I = Comps.begin(),<br>
> + E = Comps.end();<br>
> + I != E; ++I) {<br>
> + Completions.push_back(LineEditor::Completion(I->TypedText, I->MatcherDecl));<br>
> + }<br>
> + return QueryRef();<br>
> +}<br>
> +<br>
> QueryRef QueryParser::doParse() {<br>
> StringRef CommandStr;<br>
> ParsedQueryKind QKind = lexOrCompleteWord<ParsedQueryKind>(CommandStr)<br>
> .Case("", PQK_NoOp)<br>
> .Case("help", PQK_Help)<br>
> .Case("m", PQK_Match, /*IsCompletion=*/false)<br>
> + .Case("let", PQK_Let)<br>
> .Case("match", PQK_Match)<br>
> .Case("set", PQK_Set)<br>
> + .Case("unlet", PQK_Unlet)<br>
> .Default(PQK_Invalid);<br>
><br>
> + QuerySessionSema S(QS);<br>
> +<br>
> switch (QKind) {<br>
> case PQK_NoOp:<br>
> return new NoOpQuery;<br>
> @@ -163,29 +203,36 @@ QueryRef QueryParser::doParse() {<br>
> case PQK_Help:<br>
> return endQuery(new HelpQuery);<br>
><br>
> + case PQK_Let: {<br>
> + StringRef Name = lexWord();<br>
> +<br>
> + if (Name.empty())<br>
> + return new InvalidQuery("expected variable name");<br>
> +<br>
> + if (CompletionPos)<br>
> + return completeMatcherExpression();<br>
> +<br>
> + Diagnostics Diag;<br>
> + ast_matchers::dynamic::VariantValue Value;<br>
> + if (!Parser::parseExpression(StringRef(Begin, End - Begin), &S, &Value,<br>
> + &Diag)) {<br>
> + return makeInvalidQueryFromDiagnostics(Diag);<br>
> + }<br>
> +<br>
> + return new LetQuery(Name, Value);<br>
> + }<br>
> +<br>
> case PQK_Match: {<br>
> - if (CompletionPos) {<br>
> - std::vector<MatcherCompletion> Comps = Parser::completeExpression(<br>
> - StringRef(Begin, End - Begin), CompletionPos - Begin);<br>
> - for (std::vector<MatcherCompletion>::iterator I = Comps.begin(),<br>
> - E = Comps.end();<br>
> - I != E; ++I) {<br>
> - Completions.push_back(<br>
> - LineEditor::Completion(I->TypedText, I->MatcherDecl));<br>
> - }<br>
> - return QueryRef();<br>
> - } else {<br>
> - Diagnostics Diag;<br>
> - Optional<DynTypedMatcher> Matcher =<br>
> - Parser::parseMatcherExpression(StringRef(Begin, End - Begin), &Diag);<br>
> - if (!Matcher) {<br>
> - std::string ErrStr;<br>
> - llvm::raw_string_ostream OS(ErrStr);<br>
> - Diag.printToStreamFull(OS);<br>
> - return new InvalidQuery(OS.str());<br>
> - }<br>
> - return new MatchQuery(*Matcher);<br>
> + if (CompletionPos)<br>
> + return completeMatcherExpression();<br>
> +<br>
> + Diagnostics Diag;<br>
> + Optional<DynTypedMatcher> Matcher = Parser::parseMatcherExpression(<br>
> + StringRef(Begin, End - Begin), &S, &Diag);<br>
> + if (!Matcher) {<br>
> + return makeInvalidQueryFromDiagnostics(Diag);<br>
> }<br>
> + return new MatchQuery(*Matcher);<br>
> }<br>
><br>
> case PQK_Set: {<br>
> @@ -214,6 +261,15 @@ QueryRef QueryParser::doParse() {<br>
> return endQuery(Q);<br>
> }<br>
><br>
> + case PQK_Unlet: {<br>
> + StringRef Name = lexWord();<br>
> +<br>
> + if (Name.empty())<br>
> + return new InvalidQuery("expected variable name");<br>
> +<br>
> + return endQuery(new LetQuery(Name, {}));<br>
<br>
This commit broke the MSVC build bots (because of the {}):<br>
<a href="http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/8179" target="_blank">http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/8179</a><br>
<span class="HOEnZb"><font color="#888888"><br>
~Aaron<br>
</font></span></blockquote></div><br></div></div></div>