r356095 - [LibTooling] Add retrieval of extended AST-node source to FixIt library

2019-03-13 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Mar 13 12:48:51 2019
New Revision: 356095

URL: http://llvm.org/viewvc/llvm-project?rev=356095&view=rev
Log:
[LibTooling] Add retrieval of extended AST-node source to FixIt library

Summary:
Introduces variants of `getText` and `getSourceRange` that extract the source 
text of an AST node potentially with a trailing token.

Some of the new functions manipulate `CharSourceRange`s, rather than 
`SourceRange`s, because they document and dynamically enforce their type.  So, 
this revision also updates the corresponding existing FixIt functions to 
manipulate `CharSourceRange`s.  This change is not strictly necessary, but 
seems like the correct choice, to keep the API self-consistent.

This revision is the first in a series intended to improve the abstractions 
available to users for writing source-to-source transformations.  A full 
discussion of the end goal can be found on the cfe-dev list with subject "[RFC] 
Easier source-to-source transformations with clang tooling".

Reviewers: ilya-biryukov

Reviewed By: ilya-biryukov

Subscribers: kimgr, riccibruno, JonasToth, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58556

Modified:
cfe/trunk/include/clang/Tooling/FixIt.h
cfe/trunk/lib/Tooling/FixIt.cpp
cfe/trunk/unittests/Tooling/FixItTest.cpp

Modified: cfe/trunk/include/clang/Tooling/FixIt.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/FixIt.h?rev=356095&r1=356094&r2=356095&view=diff
==
--- cfe/trunk/include/clang/Tooling/FixIt.h (original)
+++ cfe/trunk/include/clang/Tooling/FixIt.h Wed Mar 13 12:48:51 2019
@@ -20,36 +20,81 @@
 #define LLVM_CLANG_TOOLING_FIXIT_H
 
 #include "clang/AST/ASTContext.h"
+#include "clang/Basic/TokenKinds.h"
 
 namespace clang {
 namespace tooling {
 namespace fixit {
 
 namespace internal {
-StringRef getText(SourceRange Range, const ASTContext &Context);
+StringRef getText(CharSourceRange Range, const ASTContext &Context);
 
-/// Returns the SourceRange of a SourceRange. This identity function is
-///used by the following template abstractions.
-inline SourceRange getSourceRange(const SourceRange &Range) { return Range; }
+/// Returns the token CharSourceRange corresponding to \p Range.
+inline CharSourceRange getSourceRange(const SourceRange &Range) {
+  return CharSourceRange::getTokenRange(Range);
+}
 
-/// Returns the SourceRange of the token at Location \p Loc.
-inline SourceRange getSourceRange(const SourceLocation &Loc) {
-  return SourceRange(Loc);
+/// Returns the CharSourceRange of the token at Location \p Loc.
+inline CharSourceRange getSourceRange(const SourceLocation &Loc) {
+  return CharSourceRange::getTokenRange(Loc, Loc);
 }
 
-/// Returns the SourceRange of an given Node. \p Node is typically a
+/// Returns the CharSourceRange of an given Node. \p Node is typically a
 ///'Stmt', 'Expr' or a 'Decl'.
-template  SourceRange getSourceRange(const T &Node) {
-  return Node.getSourceRange();
+template  CharSourceRange getSourceRange(const T &Node) {
+  return CharSourceRange::getTokenRange(Node.getSourceRange());
 }
+
+/// Extends \p Range to include the token \p Next, if it immediately follows 
the
+/// end of the range. Otherwise, returns \p Range unchanged.
+CharSourceRange maybeExtendRange(CharSourceRange Range, tok::TokenKind Next,
+ ASTContext &Context);
 } // end namespace internal
 
-// Returns a textual representation of \p Node.
+/// Returns a textual representation of \p Node.
 template 
 StringRef getText(const T &Node, const ASTContext &Context) {
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
+/// Returns the source range spanning the node, extended to include \p Next, if
+/// it immediately follows \p Node. Otherwise, returns the normal range of \p
+/// Node.  See comments on `getExtendedText()` for examples.
+template 
+CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next,
+ ASTContext &Context) {
+  return internal::maybeExtendRange(internal::getSourceRange(Node), Next,
+Context);
+}
+
+/// Returns the source text of the node, extended to include \p Next, if it
+/// immediately follows the node. Otherwise, returns the text of just \p Node.
+///
+/// For example, given statements S1 and S2 below:
+/// \code
+///   {
+/// // S1:
+/// if (!x) return foo();
+/// // S2:
+/// if (!x) { return 3; }
+//}
+/// \endcode
+/// then
+/// \code
+///   getText(S1, Context) = "if (!x) return foo()"
+///   getExtendedText(S1, tok::TokenKind::semi, Context)
+/// = "if (!x) return foo();"
+///   getExtendedText(*S1.getThen(), tok::TokenKind::semi, Context)
+/// = "return foo();"
+///   getExtendedText(*S2.getThen(), tok::TokenKind::semi, Context)
+/// = getText(S2, Context) = "{ return 3; }"
+/// \endco

r357576 - [LibTooling] Add Transformer, a library for source-to-source transformations.

2019-04-03 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Apr  3 06:05:19 2019
New Revision: 357576

URL: http://llvm.org/viewvc/llvm-project?rev=357576&view=rev
Log:
[LibTooling] Add Transformer, a library for source-to-source transformations.

Summary: Adds a basic version of Transformer, a library supporting the concise 
specification of clang-based source-to-source transformations.  A full 
discussion of the end goal can be found on the cfe-dev list with subject "[RFC] 
Easier source-to-source transformations with clang tooling".

Reviewers: ilya-biryukov

Reviewed By: ilya-biryukov

Subscribers: mgorny, jfb, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D59376

Added:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp
Modified:
cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
cfe/trunk/unittests/Tooling/CMakeLists.txt

Added: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=357576&view=auto
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (added)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Wed Apr  3 
06:05:19 2019
@@ -0,0 +1,210 @@
+//===--- Transformer.h - Clang source-rewriting library -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+///  \file
+///  Defines a library supporting the concise specification of clang-based
+///  source-to-source transformations.
+///
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_
+#define LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace tooling {
+/// Determines the part of the AST node to replace.  We support this to work
+/// around the fact that the AST does not differentiate various syntactic
+/// elements into their own nodes, so users can specify them relative to a 
node,
+/// instead.
+enum class NodePart {
+  /// The node itself.
+  Node,
+  /// Given a \c MemberExpr, selects the member's token.
+  Member,
+  /// Given a \c NamedDecl or \c CxxCtorInitializer, selects that token of the
+  /// relevant name, not including qualifiers.
+  Name,
+};
+
+using TextGenerator =
+std::function;
+
+/// Description of a source-code transformation.
+//
+// A *rewrite rule* describes a transformation of source code. It has the
+// following components:
+//
+// * Matcher: the pattern term, expressed as clang matchers (with Transformer
+//   extensions).
+//
+// * Target: the source code impacted by the rule. This identifies an AST node,
+//   or part thereof (\c TargetPart), whose source range indicates the extent 
of
+//   the replacement applied by the replacement term.  By default, the extent 
is
+//   the node matched by the pattern term (\c NodePart::Node). Target's are
+//   typed (\c TargetKind), which guides the determination of the node extent
+//   and might, in the future, statically constrain the set of eligible
+//   NodeParts for a given node.
+//
+// * Replacement: a function that produces a replacement string for the target,
+//   based on the match result.
+//
+// * Explanation: explanation of the rewrite.  This will be displayed to the
+//   user, where possible (for example, in clang-tidy fix descriptions).
+//
+// Rules have an additional, implicit, component: the parameters. These are
+// portions of the pattern which are left unspecified, yet named so that we can
+// reference them in the replacement term.  The structure of parameters can be
+// partially or even fully specified, in which case they serve just to identify
+// matched nodes for later reference rather than abstract over portions of the
+// AST.  However, in all cases, we refer to named portions of the pattern as
+// parameters.
+//
+// RewriteRule is constructed in a "fluent" style, by creating a builder and
+// chaining setters of individual components.
+// \code
+//   RewriteRule MyRule = buildRule(functionDecl(...)).replaceWith(...);
+// \endcode
+//
+// The \c Transformer class should then be used to apply the rewrite rule and
+// obtain the corresponding replacements.
+struct RewriteRule {
+  // `Matcher` describes the cont

Re: [PATCH] D59376: [LibTooling] Add Transformer, a library for source-to-source transformations.

2019-04-03 Thread Yitzhak Mandelbaum via cfe-commits
Thanks.  Do you have build command I can run before/after to verify my fix
before I submit?

On Wed, Apr 3, 2019 at 12:43 PM Alexey Bataev via Phabricator <
revi...@reviews.llvm.org> wrote:

> ABataev added a comment.
>
> Patch breaks the build with the shared libraries, for example,
> http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage/builds/9498.
> Seems to me, you need to add an extra dependency on clangTooling.
> clangToolingCore is not enough.
>
>
> Repository:
>   rC Clang
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D59376/new/
>
> https://reviews.llvm.org/D59376
>
>
>
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D59376: [LibTooling] Add Transformer, a library for source-to-source transformations.

2019-04-03 Thread Yitzhak Mandelbaum via cfe-commits
https://reviews.llvm.org/D60213 for the record

On Wed, Apr 3, 2019 at 12:55 PM Yitzhak Mandelbaum 
wrote:

> Thanks.  Do you have build command I can run before/after to verify my fix
> before I submit?
>
> On Wed, Apr 3, 2019 at 12:43 PM Alexey Bataev via Phabricator <
> revi...@reviews.llvm.org> wrote:
>
>> ABataev added a comment.
>>
>> Patch breaks the build with the shared libraries, for example,
>> http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage/builds/9498.
>> Seems to me, you need to add an extra dependency on clangTooling.
>> clangToolingCore is not enough.
>>
>>
>> Repository:
>>   rC Clang
>>
>> CHANGES SINCE LAST ACTION
>>   https://reviews.llvm.org/D59376/new/
>>
>> https://reviews.llvm.org/D59376
>>
>>
>>
>>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D59376: [LibTooling] Add Transformer, a library for source-to-source transformations.

2019-04-03 Thread Yitzhak Mandelbaum via cfe-commits
I'll revert the change.

On Wed, Apr 3, 2019 at 1:00 PM Yitzhak Mandelbaum 
wrote:

> https://reviews.llvm.org/D60213 for the record
>
> On Wed, Apr 3, 2019 at 12:55 PM Yitzhak Mandelbaum 
> wrote:
>
>> Thanks.  Do you have build command I can run before/after to verify my
>> fix before I submit?
>>
>> On Wed, Apr 3, 2019 at 12:43 PM Alexey Bataev via Phabricator <
>> revi...@reviews.llvm.org> wrote:
>>
>>> ABataev added a comment.
>>>
>>> Patch breaks the build with the shared libraries, for example,
>>> http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage/builds/9498.
>>> Seems to me, you need to add an extra dependency on clangTooling.
>>> clangToolingCore is not enough.
>>>
>>>
>>> Repository:
>>>   rC Clang
>>>
>>> CHANGES SINCE LAST ACTION
>>>   https://reviews.llvm.org/D59376/new/
>>>
>>> https://reviews.llvm.org/D59376
>>>
>>>
>>>
>>>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D60213: Add clangTooling dependency to fix the build.

2019-04-03 Thread Yitzhak Mandelbaum via cfe-commits
That would be great, thank you.

On Wed, Apr 3, 2019 at 1:28 PM Alexey Bataev via Phabricator <
revi...@reviews.llvm.org> wrote:

> ABataev added a comment.
>
> I can revert it for you, if you want
>
>
> Repository:
>   rG LLVM Github Monorepo
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D60213/new/
>
> https://reviews.llvm.org/D60213
>
>
>
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D59376: [LibTooling] Add Transformer, a library for source-to-source transformations.

2019-04-03 Thread Yitzhak Mandelbaum via cfe-commits
Alexey, thanks for reverting the change. Can you expand on why a dependency
from libToolingRefactor to libTooling causes a cycle in the dep graph? In
particular, I can't find the reverse dependency libTooling ->
libToolingRefactor. If you can expand on that (I presume its a chain rather
than a direct dependency?) that would be really helpful.

thanks!

On Wed, Apr 3, 2019 at 1:29 PM Yitzhak Mandelbaum 
wrote:

> I'll revert the change.
>
> On Wed, Apr 3, 2019 at 1:00 PM Yitzhak Mandelbaum 
> wrote:
>
>> https://reviews.llvm.org/D60213 for the record
>>
>> On Wed, Apr 3, 2019 at 12:55 PM Yitzhak Mandelbaum 
>> wrote:
>>
>>> Thanks.  Do you have build command I can run before/after to verify my
>>> fix before I submit?
>>>
>>> On Wed, Apr 3, 2019 at 12:43 PM Alexey Bataev via Phabricator <
>>> revi...@reviews.llvm.org> wrote:
>>>
 ABataev added a comment.

 Patch breaks the build with the shared libraries, for example,
 http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage/builds/9498.
 Seems to me, you need to add an extra dependency on clangTooling.
 clangToolingCore is not enough.


 Repository:
   rC Clang

 CHANGES SINCE LAST ACTION
   https://reviews.llvm.org/D59376/new/

 https://reviews.llvm.org/D59376






smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D59376: [LibTooling] Add Transformer, a library for source-to-source transformations.

2019-04-03 Thread Yitzhak Mandelbaum via cfe-commits
Thanks.  Any idea why AtomicChange.cpp's inclusion of
clang/Tooling/ReplacementsYaml.h
doesn't cause the same problem?
https://github.com/llvm/llvm-project/blob/master/clang/lib/Tooling/Refactoring/AtomicChange.cpp

On Wed, Apr 3, 2019 at 2:11 PM Alexey Bataev  wrote:

> The problem is that libToolingRefactor is a part of libTooling. And you
> have the dependency from the Tooling/Refactor subdirectory to the outer one
> Tooling/ directory. And it means that libToolingRefactor is a part of
> libTooling, but it must depend on libTooling itself.
>
> -
> Best regards,
> Alexey Bataev
>
> 03.04.2019 14:08, Yitzhak Mandelbaum пишет:
>
> Alexey, thanks for reverting the change. Can you expand on why a
> dependency from libToolingRefactor to libTooling causes a cycle in the dep
> graph? In particular, I can't find the reverse dependency libTooling ->
> libToolingRefactor. If you can expand on that (I presume its a chain rather
> than a direct dependency?) that would be really helpful.
>
> thanks!
>
> On Wed, Apr 3, 2019 at 1:29 PM Yitzhak Mandelbaum 
> wrote:
>
>> I'll revert the change.
>>
>> On Wed, Apr 3, 2019 at 1:00 PM Yitzhak Mandelbaum 
>> wrote:
>>
>>> https://reviews.llvm.org/D60213 for the record
>>>
>>> On Wed, Apr 3, 2019 at 12:55 PM Yitzhak Mandelbaum 
>>> wrote:
>>>
 Thanks.  Do you have build command I can run before/after to verify my
 fix before I submit?

 On Wed, Apr 3, 2019 at 12:43 PM Alexey Bataev via Phabricator <
 revi...@reviews.llvm.org> wrote:

> ABataev added a comment.
>
> Patch breaks the build with the shared libraries, for example,
> http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage/builds/9498.
> Seems to me, you need to add an extra dependency on clangTooling.
> clangToolingCore is not enough.
>
>
> Repository:
>   rC Clang
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D59376/new/
>
> https://reviews.llvm.org/D59376
>
>
>
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r357764 - [LibTooling] Add "SourceCode" library for functions relating to source-code manipulation.

2019-04-05 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Apr  5 07:05:03 2019
New Revision: 357764

URL: http://llvm.org/viewvc/llvm-project?rev=357764&view=rev
Log:
[LibTooling] Add "SourceCode" library for functions relating to source-code 
manipulation.

Summary:
Introduces a utility library in Refactoring/ to collect routines related to
source-code manipulation.  In this change, we move "extended-range" functions
from the FixIt library (in clangTooling) to this new library.

We need to use this functionality in Refactoring/ and cannot access it if it
resides in Tooling/, because that would cause clangToolingRefactor to depend on
clangTooling, which would be a circular dependency.

Reviewers: ilya-biryukov, ioeric

Reviewed By: ilya-biryukov

Subscribers: mgorny, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D60269

Added:
cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h
cfe/trunk/lib/Tooling/Refactoring/SourceCode.cpp
cfe/trunk/unittests/Tooling/SourceCodeTest.cpp
Modified:
cfe/trunk/include/clang/Tooling/FixIt.h
cfe/trunk/lib/Tooling/FixIt.cpp
cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
cfe/trunk/unittests/Tooling/CMakeLists.txt
cfe/trunk/unittests/Tooling/FixItTest.cpp

Modified: cfe/trunk/include/clang/Tooling/FixIt.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/FixIt.h?rev=357764&r1=357763&r2=357764&view=diff
==
--- cfe/trunk/include/clang/Tooling/FixIt.h (original)
+++ cfe/trunk/include/clang/Tooling/FixIt.h Fri Apr  5 07:05:03 2019
@@ -20,7 +20,6 @@
 #define LLVM_CLANG_TOOLING_FIXIT_H
 
 #include "clang/AST/ASTContext.h"
-#include "clang/Basic/TokenKinds.h"
 
 namespace clang {
 namespace tooling {
@@ -44,11 +43,6 @@ inline CharSourceRange getSourceRange(co
 template  CharSourceRange getSourceRange(const T &Node) {
   return CharSourceRange::getTokenRange(Node.getSourceRange());
 }
-
-/// Extends \p Range to include the token \p Next, if it immediately follows 
the
-/// end of the range. Otherwise, returns \p Range unchanged.
-CharSourceRange maybeExtendRange(CharSourceRange Range, tok::TokenKind Next,
- ASTContext &Context);
 } // end namespace internal
 
 /// Returns a textual representation of \p Node.
@@ -57,44 +51,6 @@ StringRef getText(const T &Node, const A
   return internal::getText(internal::getSourceRange(Node), Context);
 }
 
-/// Returns the source range spanning the node, extended to include \p Next, if
-/// it immediately follows \p Node. Otherwise, returns the normal range of \p
-/// Node.  See comments on `getExtendedText()` for examples.
-template 
-CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next,
- ASTContext &Context) {
-  return internal::maybeExtendRange(internal::getSourceRange(Node), Next,
-Context);
-}
-
-/// Returns the source text of the node, extended to include \p Next, if it
-/// immediately follows the node. Otherwise, returns the text of just \p Node.
-///
-/// For example, given statements S1 and S2 below:
-/// \code
-///   {
-/// // S1:
-/// if (!x) return foo();
-/// // S2:
-/// if (!x) { return 3; }
-///   }
-/// \endcode
-/// then
-/// \code
-///   getText(S1, Context) = "if (!x) return foo()"
-///   getExtendedText(S1, tok::TokenKind::semi, Context)
-/// = "if (!x) return foo();"
-///   getExtendedText(*S1.getThen(), tok::TokenKind::semi, Context)
-/// = "return foo();"
-///   getExtendedText(*S2.getThen(), tok::TokenKind::semi, Context)
-/// = getText(S2, Context) = "{ return 3; }"
-/// \endcode
-template 
-StringRef getExtendedText(const T &Node, tok::TokenKind Next,
-  ASTContext &Context) {
-  return internal::getText(getExtendedRange(Node, Next, Context), Context);
-}
-
 // Returns a FixItHint to remove \p Node.
 // TODO: Add support for related syntactical elements (i.e. comments, ...).
 template  FixItHint createRemoval(const T &Node) {

Added: cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h?rev=357764&view=auto
==
--- cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h (added)
+++ cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h Fri Apr  5 
07:05:03 2019
@@ -0,0 +1,77 @@
+//===--- SourceCode.h - Source code manipulation routines ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file provides functions that simplify extraction of source code.
+//
+//===---

r357768 - [LibTooling] Add Transformer, a library for source-to-source transformations.

2019-04-05 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Apr  5 08:14:05 2019
New Revision: 357768

URL: http://llvm.org/viewvc/llvm-project?rev=357768&view=rev
Log:
[LibTooling] Add Transformer, a library for source-to-source transformations.

Summary: Adds a basic version of Transformer, a library supporting the concise 
specification of clang-based source-to-source transformations.  A full 
discussion of the end goal can be found on the cfe-dev list with subject "[RFC] 
Easier source-to-source transformations with clang tooling".

Reviewers: ilya-biryukov

Reviewed By: ilya-biryukov

Subscribers: ioeric, ABataev, mgorny, jfb, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D59376

Added:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp
Modified:
cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
cfe/trunk/unittests/Tooling/CMakeLists.txt

Added: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=357768&view=auto
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (added)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Fri Apr  5 
08:14:05 2019
@@ -0,0 +1,210 @@
+//===--- Transformer.h - Clang source-rewriting library -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+///  \file
+///  Defines a library supporting the concise specification of clang-based
+///  source-to-source transformations.
+///
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_
+#define LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace tooling {
+/// Determines the part of the AST node to replace.  We support this to work
+/// around the fact that the AST does not differentiate various syntactic
+/// elements into their own nodes, so users can specify them relative to a 
node,
+/// instead.
+enum class NodePart {
+  /// The node itself.
+  Node,
+  /// Given a \c MemberExpr, selects the member's token.
+  Member,
+  /// Given a \c NamedDecl or \c CxxCtorInitializer, selects that token of the
+  /// relevant name, not including qualifiers.
+  Name,
+};
+
+using TextGenerator =
+std::function;
+
+/// Description of a source-code transformation.
+//
+// A *rewrite rule* describes a transformation of source code. It has the
+// following components:
+//
+// * Matcher: the pattern term, expressed as clang matchers (with Transformer
+//   extensions).
+//
+// * Target: the source code impacted by the rule. This identifies an AST node,
+//   or part thereof (\c TargetPart), whose source range indicates the extent 
of
+//   the replacement applied by the replacement term.  By default, the extent 
is
+//   the node matched by the pattern term (\c NodePart::Node). Target's are
+//   typed (\c TargetKind), which guides the determination of the node extent
+//   and might, in the future, statically constrain the set of eligible
+//   NodeParts for a given node.
+//
+// * Replacement: a function that produces a replacement string for the target,
+//   based on the match result.
+//
+// * Explanation: explanation of the rewrite.  This will be displayed to the
+//   user, where possible (for example, in clang-tidy fix descriptions).
+//
+// Rules have an additional, implicit, component: the parameters. These are
+// portions of the pattern which are left unspecified, yet named so that we can
+// reference them in the replacement term.  The structure of parameters can be
+// partially or even fully specified, in which case they serve just to identify
+// matched nodes for later reference rather than abstract over portions of the
+// AST.  However, in all cases, we refer to named portions of the pattern as
+// parameters.
+//
+// RewriteRule is constructed in a "fluent" style, by creating a builder and
+// chaining setters of individual components.
+// \code
+//   RewriteRule MyRule = buildRule(functionDecl(...)).replaceWith(...);
+// \endcode
+//
+// The \c Transformer class should then be used to apply the rewrite rule and
+// obtain the corresponding replacements.
+struct RewriteRule {
+  // `Matcher` d

r358691 - [LibTooling] Add Stencil library for format-string style codegen.

2019-04-18 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Apr 18 10:23:01 2019
New Revision: 358691

URL: http://llvm.org/viewvc/llvm-project?rev=358691&view=rev
Log:
[LibTooling] Add Stencil library for format-string style codegen.

Summary:
This file defines the *Stencil* abstraction: a code-generating object, 
parameterized by named references to (bound) AST nodes.  Given a match result, 
a stencil can be evaluated to a string of source code.

A stencil is similar in spirit to a format string: it is composed of a series 
of raw text strings, references to nodes (the parameters) and helper 
code-generation operations.

See thread on cfe-dev list with subject "[RFC] Easier source-to-source 
transformations with clang tooling" for background.

Reviewers: sbenza

Reviewed By: sbenza

Subscribers: ilya-biryukov, mgorny, jfb, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D59371

Added:
cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
cfe/trunk/unittests/Tooling/StencilTest.cpp
Modified:
cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
cfe/trunk/unittests/Tooling/CMakeLists.txt

Added: cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h?rev=358691&view=auto
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h (added)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h Thu Apr 18 10:23:01 
2019
@@ -0,0 +1,161 @@
+//===--- Stencil.h - Stencil class --*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// /file
+/// This file defines the *Stencil* abstraction: a code-generating object,
+/// parameterized by named references to (bound) AST nodes.  Given a match
+/// result, a stencil can be evaluated to a string of source code.
+///
+/// A stencil is similar in spirit to a format string: it is composed of a
+/// series of raw text strings, references to nodes (the parameters) and helper
+/// code-generation operations.
+///
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_STENCIL_H_
+#define LLVM_CLANG_TOOLING_REFACTOR_STENCIL_H_
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+
+namespace clang {
+namespace tooling {
+
+/// A stencil is represented as a sequence of "parts" that can each 
individually
+/// generate a code string based on a match result.  The different kinds of
+/// parts include (raw) text, references to bound nodes and assorted operations
+/// on bound nodes.
+///
+/// Users can create custom Stencil operations by implementing this interface.
+class StencilPartInterface {
+public:
+  virtual ~StencilPartInterface() = default;
+
+  /// Evaluates this part to a string and appends it to \c Result.  \c Result 
is
+  /// undefined in the case of an error.
+  virtual llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &Match,
+   std::string *Result) const = 0;
+
+  virtual bool isEqual(const StencilPartInterface &other) const = 0;
+
+  const void *typeId() const { return TypeId; }
+
+protected:
+  StencilPartInterface(const void *DerivedId) : TypeId(DerivedId) {}
+
+  // Since this is an abstract class, copying/assigning only make sense for
+  // derived classes implementing `clone()`.
+  StencilPartInterface(const StencilPartInterface &) = default;
+  StencilPartInterface &operator=(const StencilPartInterface &) = default;
+
+  /// Unique identifier of the concrete type of this instance.  Supports safe
+  /// downcasting.
+  const void *TypeId;
+};
+
+/// A copyable facade for a std::unique_ptr. Copies 
result
+/// in a copy of the underlying pointee object.
+class StencilPart {
+public:
+  explicit StencilPart(std::shared_ptr Impl)
+  : Impl(std::move(Impl)) {}
+
+  /// See `StencilPartInterface::eval()`.
+  llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &Match,
+   std::string *Result) const {
+return Impl->eval(Match, Result);
+  }
+
+  bool operator==(const StencilPart &Other) const {
+if (Impl == Other.Impl)
+  return true;
+if (Impl == nullptr || Other.Impl == nullptr)
+  return false;
+return Impl->isEqual(*Other.Impl);
+  }
+
+private:
+  std::shared_ptr Impl;
+};
+
+/// A sequence of code fragments, references to parameters and code-generation
+/// operations that together can be evaluated to (a fragment of) source code

r358697 - [LibTooling] Extend Transformer to support multiple simultaneous changes.

2019-04-18 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Apr 18 10:52:24 2019
New Revision: 358697

URL: http://llvm.org/viewvc/llvm-project?rev=358697&view=rev
Log:
[LibTooling] Extend Transformer to support multiple simultaneous changes.

Summary: This revision allows users to specify independent changes to multiple 
(related) sections of the input.  Previously, only a single section of input 
could be selected for replacement.

Reviewers: ilya-biryukov

Reviewed By: ilya-biryukov

Subscribers: jfb, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D60408

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=358697&r1=358696&r2=358697&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Thu Apr 18 
10:52:24 2019
@@ -20,13 +20,13 @@
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
 #include "clang/Tooling/Refactoring/AtomicChange.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Error.h"
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 
 namespace clang {
 namespace tooling {
@@ -47,6 +47,98 @@ enum class NodePart {
 using TextGenerator =
 std::function;
 
+/// Wraps a string as a TextGenerator.
+inline TextGenerator text(std::string M) {
+  return [M](const ast_matchers::MatchFinder::MatchResult &) { return M; };
+}
+
+// Description of a source-code edit, expressed in terms of an AST node.
+// Includes: an ID for the (bound) node, a selector for source related to the
+// node, a replacement and, optionally, an explanation for the edit.
+//
+// * Target: the source code impacted by the rule. This identifies an AST node,
+//   or part thereof (\c Part), whose source range indicates the extent of the
+//   replacement applied by the replacement term.  By default, the extent is 
the
+//   node matched by the pattern term (\c NodePart::Node). Target's are typed
+//   (\c Kind), which guides the determination of the node extent.
+//
+// * Replacement: a function that produces a replacement string for the target,
+//   based on the match result.
+//
+// * Note: (optional) a note specifically for this edit, potentially 
referencing
+//   elements of the match.  This will be displayed to the user, where 
possible;
+//   for example, in clang-tidy diagnostics.  Use of notes should be rare --
+//   explanations of the entire rewrite should be set in the rule
+//   (`RewriteRule::Explanation`) instead.  Notes serve the rare cases wherein
+//   edit-specific diagnostics are required.
+//
+// `ASTEdit` should be built using the `change` convenience fucntions. For
+// example,
+// \code
+//   change(fun, NodePart::Name, "Frodo")
+// \endcode
+// Or, if we use Stencil for the TextGenerator:
+// \code
+//   change(thenNode, stencil::cat("{", thenNode, "}"))
+//   change(call, NodePart::Args, stencil::cat(x, ",", y))
+// .note("argument order changed.")
+// \endcode
+// Or, if you are changing the node corresponding to the rule's matcher, you 
can
+// use the single-argument override of \c change:
+// \code
+//   change("different_expr")
+// \endcode
+struct ASTEdit {
+  // The (bound) id of the node whose source will be replaced.  This id should
+  // never be the empty string.
+  std::string Target;
+  ast_type_traits::ASTNodeKind Kind;
+  NodePart Part;
+  TextGenerator Replacement;
+  TextGenerator Note;
+};
+
+// Convenience functions for creating \c ASTEdits.  They all must be explicitly
+// instantiated with the desired AST type.  Each overload includes both \c
+// std::string and \c TextGenerator versions.
+
+// FIXME: For overloads taking a \c NodePart, constrain the valid values of \c
+// Part based on the type \c T.
+template 
+ASTEdit change(StringRef Target, NodePart Part, TextGenerator Replacement) {
+  ASTEdit E;
+  E.Target = Target.str();
+  E.Kind = ast_type_traits::ASTNodeKind::getFromNodeKind();
+  E.Part = Part;
+  E.Replacement = std::move(Replacement);
+  return E;
+}
+
+template 
+ASTEdit change(StringRef Target, NodePart Part, std::string Replacement) {
+  return change(Target, Part, text(std::move(Replacement)));
+}
+
+/// Variant of \c change for which the NodePart defaults to the whole node.
+template 
+ASTEdit change(StringRef Target, TextGenerator Replacement) {
+  return change(Target, NodePart::Node, std::move(Replacement));
+}
+
+/// Variant of \c change for which the NodePart defaults to the whole node.
+template 
+ASTEdit change(StringRef Target, std::string Replacement) {
+  return change(Target, text(std::move(Replacement)));
+}
+
+/// Variant of \c change t

r358705 - [LibTooling] Fix build breakage from commit 7b7ce6683ee.

2019-04-18 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Apr 18 12:19:01 2019
New Revision: 358705

URL: http://llvm.org/viewvc/llvm-project?rev=358705&view=rev
Log:
[LibTooling] Fix build breakage from commit 7b7ce6683ee.

On configurations with -Werror,-Wmissing-field-initializers, the commit does 
not compile. This commit fixes the offending line.

Original Differential Revision: https://reviews.llvm.org/D60408

Modified:
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp

Modified: cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp?rev=358705&r1=358704&r2=358705&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp Thu Apr 18 12:19:01 2019
@@ -172,7 +172,8 @@ RewriteRule tooling::makeRule(ast_matche
   SmallVector Edits) {
   M.setAllowBind(true);
   // `tryBind` is guaranteed to succeed, because `AllowBind` was set to true.
-  return RewriteRule{*M.tryBind(RewriteRule::RootId), std::move(Edits)};
+  return RewriteRule{*M.tryBind(RewriteRule::RootId), std::move(Edits),
+ nullptr};
 }
 
 constexpr llvm::StringLiteral RewriteRule::RootId;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r359468 - [LibTooling] Fix unneeded use of unique_ptr where shared_ptr is expected.

2019-04-29 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Mon Apr 29 09:57:40 2019
New Revision: 359468

URL: http://llvm.org/viewvc/llvm-project?rev=359468&view=rev
Log:
[LibTooling] Fix unneeded use of unique_ptr where shared_ptr is expected.

Summary: This fixes a few places in the Stencil implementation where a 
unique_ptr is created at a callsite that expects shared_ptr. Since the former 
implicitly converts to the latter, the code compiles and runs correctly as is.  
But, there's no reason to involve unique_ptr -- the current code was leftover 
from a previous version in which unique_ptr was the expected type.

Reviewers: sbenza

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D61005

Modified:
cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp

Modified: cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp?rev=359468&r1=359467&r2=359468&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp Mon Apr 29 09:57:40 2019
@@ -16,6 +16,7 @@
 #include "clang/Tooling/Refactoring/SourceCode.h"
 #include "llvm/Support/Errc.h"
 #include 
+#include 
 #include 
 
 using namespace clang;
@@ -183,17 +184,17 @@ Stencil::eval(const MatchFinder::MatchRe
 }
 
 StencilPart stencil::text(StringRef Text) {
-  return StencilPart(llvm::make_unique(Text));
+  return StencilPart(std::make_shared(Text));
 }
 
 StencilPart stencil::node(StringRef Id) {
-  return StencilPart(llvm::make_unique(Id, 
SemiAssociation::Inferred));
+  return StencilPart(std::make_shared(Id, SemiAssociation::Inferred));
 }
 
 StencilPart stencil::sNode(StringRef Id) {
-  return StencilPart(llvm::make_unique(Id, SemiAssociation::Always));
+  return StencilPart(std::make_shared(Id, SemiAssociation::Always));
 }
 
 StencilPart stencil::dPrint(StringRef Id) {
-  return StencilPart(llvm::make_unique(Id));
+  return StencilPart(std::make_shared(Id));
 }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r359574 - [LibTooling] Change Transformer's TextGenerator to a partial function.

2019-04-30 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Tue Apr 30 09:48:33 2019
New Revision: 359574

URL: http://llvm.org/viewvc/llvm-project?rev=359574&view=rev
Log:
[LibTooling] Change Transformer's TextGenerator to a partial function.

Summary:
Changes the signature of the TextGenerator std::function to return an 
Expected
instead of std::string to allow for (non-fatal) failures.  Previously, we
expected that any failures would be expressed with assertions. However, that's
unfriendly to running the code in servers or other places that don't want their
library calls to crash the program.

Correspondingly, updates Transformer's handling of failures in TextGenerators
and the signature of `ChangeConsumer`.

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D61015

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=359574&r1=359573&r2=359574&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Tue Apr 30 
09:48:33 2019
@@ -44,12 +44,16 @@ enum class NodePart {
   Name,
 };
 
-using TextGenerator =
-std::function;
+// Note that \p TextGenerator is allowed to fail, e.g. when trying to access a
+// matched node that was not bound.  Allowing this to fail simplifies error
+// handling for interactive tools like clang-query.
+using TextGenerator = std::function(
+const ast_matchers::MatchFinder::MatchResult &)>;
 
 /// Wraps a string as a TextGenerator.
 inline TextGenerator text(std::string M) {
-  return [M](const ast_matchers::MatchFinder::MatchResult &) { return M; };
+  return [M](const ast_matchers::MatchFinder::MatchResult &)
+ -> Expected { return M; };
 }
 
 // Description of a source-code edit, expressed in terms of an AST node.
@@ -222,11 +226,13 @@ translateEdits(const ast_matchers::Match
 class Transformer : public ast_matchers::MatchFinder::MatchCallback {
 public:
   using ChangeConsumer =
-  std::function;
+  std::function Change)>;
 
-  /// \param Consumer Receives each successful rewrite as an \c AtomicChange.
-  /// Note that clients are responsible for handling the case that independent
-  /// \c AtomicChanges conflict with each other.
+  /// \param Consumer Receives each rewrite or error.  Will not necessarily be
+  /// called for each match; for example, if the rewrite is not applicable
+  /// because of macros, but doesn't fail.  Note that clients are responsible
+  /// for handling the case that independent \c AtomicChanges conflict with 
each
+  /// other.
   Transformer(RewriteRule Rule, ChangeConsumer Consumer)
   : Rule(std::move(Rule)), Consumer(std::move(Consumer)) {}
 

Modified: cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp?rev=359574&r1=359573&r2=359574&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp Tue Apr 30 09:48:33 2019
@@ -153,16 +153,19 @@ tooling::translateEdits(const MatchResul
 auto It = NodesMap.find(Edit.Target);
 assert(It != NodesMap.end() && "Edit target must be bound in the match.");
 
-Expected RangeOrErr = getTargetRange(
+Expected Range = getTargetRange(
 Edit.Target, It->second, Edit.Kind, Edit.Part, *Result.Context);
-if (auto Err = RangeOrErr.takeError())
-  return std::move(Err);
-Transformation T;
-T.Range = *RangeOrErr;
-if (T.Range.isInvalid() ||
-isOriginMacroBody(*Result.SourceManager, T.Range.getBegin()))
+if (!Range)
+  return Range.takeError();
+if (Range->isInvalid() ||
+isOriginMacroBody(*Result.SourceManager, Range->getBegin()))
   return SmallVector();
-T.Replacement = Edit.Replacement(Result);
+auto Replacement = Edit.Replacement(Result);
+if (!Replacement)
+  return Replacement.takeError();
+Transformation T;
+T.Range = *Range;
+T.Replacement = std::move(*Replacement);
 Transformations.push_back(std::move(T));
   }
   return Transformations;
@@ -194,14 +197,13 @@ void Transformer::run(const MatchResult
   Root->second.getSourceRange().getBegin());
   assert(RootLoc.isValid() && "Invalid location for Root node of match.");
 
-  auto TransformationsOrErr = translateEdits(Result, Rule.Edits);
-  if (auto Err = TransformationsOrErr.takeError()) {
-llvm::errs() << "Transformation failed: " << llvm::toString(std::move(Err))
- << "\n";
+  auto Tra

r359578 - [LibTooling] Fix broken test after r359574.

2019-04-30 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Tue Apr 30 10:24:36 2019
New Revision: 359578

URL: http://llvm.org/viewvc/llvm-project?rev=359578&view=rev
Log:
[LibTooling] Fix broken test after r359574.

r359574 changed the way that failures are reported, which broke the test 
TransformerTest.NodePartNameDeclRefFailure which detects a faiure.

Modified:
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/unittests/Tooling/TransformerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/TransformerTest.cpp?rev=359578&r1=359577&r2=359578&view=diff
==
--- cfe/trunk/unittests/Tooling/TransformerTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/TransformerTest.cpp Tue Apr 30 10:24:36 2019
@@ -251,9 +251,11 @@ TEST_F(TransformerTest, NodePartNameDecl
   )cc";
 
   StringRef Ref = "ref";
-  testRule(makeRule(declRefExpr(to(functionDecl())).bind(Ref),
-change(Ref, NodePart::Name, "good")),
-   Input, Input);
+  Transformer T(makeRule(declRefExpr(to(functionDecl())).bind(Ref),
+ change(Ref, NodePart::Name, "good")),
+consumer());
+  T.registerMatchers(&MatchFinder);
+  EXPECT_FALSE(rewrite(Input));
 }
 
 TEST_F(TransformerTest, NodePartMember) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r353523 - [clang-tidy][NFC] Test commit. Add missing comma.

2019-02-08 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Feb  8 06:57:22 2019
New Revision: 353523

URL: http://llvm.org/viewvc/llvm-project?rev=353523&view=rev
Log:
[clang-tidy][NFC] Test commit. Add missing comma.

Modified:
clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp?rev=353523&r1=353522&r2=353523&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp Fri 
Feb  8 06:57:22 2019
@@ -22,8 +22,8 @@ namespace readability {
 
 // Finds the location of the qualifying `const` token in the `FunctionDecl`'s
 // return type. Returns `None` when the return type is not `const`-qualified or
-// `const` does not appear in `Def`'s source like when the type is an alias or 
a
-// macro.
+// `const` does not appear in `Def`'s source like, when the type is an alias or
+// a macro.
 static llvm::Optional
 findConstToRemove(const FunctionDecl *Def,
   const MatchFinder::MatchResult &Result) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r353525 - [clang-tidy][NFC] Fix typo.

2019-02-08 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Feb  8 07:05:57 2019
New Revision: 353525

URL: http://llvm.org/viewvc/llvm-project?rev=353525&view=rev
Log:
[clang-tidy][NFC] Fix typo.

Fix placement of comma from previous (test) commit.

Modified:
clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp?rev=353525&r1=353524&r2=353525&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/readability/ConstReturnTypeCheck.cpp Fri 
Feb  8 07:05:57 2019
@@ -22,7 +22,7 @@ namespace readability {
 
 // Finds the location of the qualifying `const` token in the `FunctionDecl`'s
 // return type. Returns `None` when the return type is not `const`-qualified or
-// `const` does not appear in `Def`'s source like, when the type is an alias or
+// `const` does not appear in `Def`'s source, like when the type is an alias or
 // a macro.
 static llvm::Optional
 findConstToRemove(const FunctionDecl *Def,


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r353532 - [ASTMatchers][NFC] Update comments on assorted `CXXMemberCallExpr` matchers.

2019-02-08 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Feb  8 08:00:44 2019
New Revision: 353532

URL: http://llvm.org/viewvc/llvm-project?rev=353532&view=rev
Log:
[ASTMatchers][NFC] Update comments on assorted `CXXMemberCallExpr` matchers.

Specifically:

* fixes the comments on `hasObjectExpression`,
* clarifies comments on `thisPointerType` and `on`,
* adds comments to `onImplicitObjectArgument`.

It also updates associated reference docs (using the doc tool).

Reviewers: alexfh, steveire, aaron.ballman

Differential Revision: https://reviews.llvm.org/D56849

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=353532&r1=353531&r2=353532&view=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Fri Feb  8 08:00:44 2019
@@ -4810,16 +4810,20 @@ with withInitializer matching (1)
 
 
 MatcherCXXDependentScopeMemberExpr>hasObjectExpressionMatcherExpr> 
InnerMatcher
-Matches a 
member expression where the object expression is
-matched by a given matcher.
+Matches a 
member expression where the object expression is matched by a
+given matcher. Implicit object expressions are included; that is, it matches
+use of implicit `this`.
 
 Given
-  struct X { int m; };
-  void f(X x) { x.m; m; }
-memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))
-  matches "x.m" and "m"
-with hasObjectExpression(...)
-  matching "x" and the implicit object expression of "m" which has type X*.
+  struct X {
+int m;
+int f(X x) { x.m; return m; }
+  };
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")
+  matches `x.m`, but not `m`; however,
+memberExpr(hasObjectExpression(hasType(pointsTo(
+ cxxRecordDecl(hasName("X"))
+  matches `m` (aka. `this->m`), but not `x.m`.
 
 
 
@@ -4857,16 +4861,39 @@ matches 'a' in
 
 
 MatcherCXXMemberCallExpr>onImplicitObjectArgumentMatcherExpr> 
InnerMatcher
-
+Matches on 
the implicit object argument of a member call expression. Unlike
+`on`, matches the argument directly without stripping away anything.
+
+Given
+  class Y { public: void m(); };
+  Y g();
+  class X : public Y { void g(); };
+  void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); }
+cxxMemberCallExpr(onImplicitObjectArgument(hasType(
+cxxRecordDecl(hasName("Y")
+  matches `y.m()`, `x.m()` and (g()).m(), but not `x.g()`.
+cxxMemberCallExpr(on(callExpr()))
+  does not match `(g()).m()`, because the parens are not ignored.
+
+FIXME: Overload to allow directly matching types?
+
 
 
 MatcherCXXMemberCallExpr>onMatcherExpr> 
InnerMatcher
-Matches on the implicit object 
argument of a member call expression.
+Matches on the implicit object 
argument of a member call expression, after
+stripping off any parentheses or implicit casts.
 
-Example matches y.x()
-  (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))
-  class Y { public: void x(); };
-  void z() { Y y; y.x(); }
+Given
+  class Y { public: void m(); };
+  Y g();
+  class X : public Y {};
+  void z(Y y, X x) { y.m(); (g()).m(); x.m(); }
+cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")
+  matches `y.m()` and `(g()).m()`.
+cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")
+  matches `x.m()`.
+cxxMemberCallExpr(on(callExpr()))
+  matches `(g()).m()`.
 
 FIXME: Overload to allow directly matching types?
 
@@ -4878,8 +4905,20 @@ FIXME: Overload to allow directly matchi
 
 
 MatcherCXXMemberCallExpr>thisPointerTypeMatcherQualType>
 InnerMatcher
-Matches if the 
expression's type either matches the specified
-matcher, or is a pointer to a type that matches the InnerMatcher.
+Matches if the type 
of the expression's implicit object argument either
+matches the InnerMatcher, or is a pointer to a type that matches the
+InnerMatcher.
+
+Given
+  class Y { public: void m(); };
+  class X : public Y { void g(); };
+  void z() { Y y; y.m(); Y *p; p->m(); X x; x.m(); x.g(); }
+cxxMemberCallExpr(thisPointerType(hasDeclaration(
+cxxRecordDecl(hasName("Y")
+  matches `y.m()`, `p->m()` and `x.m()`.
+cxxMemberCallExpr(thisPointerType(hasDeclaration(
+cxxRecordDecl(hasName("X")
+  matches `x.g()`.
 
 
 
@@ -5984,16 +6023,20 @@ Usable as: Matcher

r354133 - Add tests for assorted `CXXMemberCallExpr` matchers.

2019-02-15 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Feb 15 06:43:03 2019
New Revision: 354133

URL: http://llvm.org/viewvc/llvm-project?rev=354133&view=rev
Log:
Add tests for assorted `CXXMemberCallExpr` matchers.

Summary: Add tests for matchers `on`, `onImplicitObjectArgument` and 
`hasObjectExpression`.

Reviewers: alexfh, steveire, aaron.ballman

Differential Revision: https://reviews.llvm.org/D56850

Modified:
cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=354133&r1=354132&r2=354133&view=diff
==
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Fri Feb 15 
06:43:03 2019
@@ -469,6 +469,95 @@ TEST(Matcher, isInstanceMessage) {
 
 }
 
+TEST(MatcherCXXMemberCallExpr, On) {
+  auto MatchesType = 
cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X");
+  EXPECT_TRUE(matches(
+  R"cc(
+struct Y {
+  void m();
+};
+struct X : public Y {};
+void z(X x) { x.m(); }
+  )cc",
+  MatchesType));
+  EXPECT_TRUE(notMatches(
+  R"cc(
+struct Y {
+  void m();
+};
+void z(Y y) { y.m(); }
+  )cc",
+  MatchesType));
+
+  // Parens are ignored.
+  auto MatchesCall = cxxMemberCallExpr(on(callExpr()));
+  EXPECT_TRUE(matches(
+  R"cc(
+struct Y {
+  void m();
+};
+Y g();
+void z(Y y) { (g()).m(); }
+  )cc",
+  MatchesCall));
+}
+
+TEST(MatcherCXXMemberCallExpr, OnImplicitObjectArgument) {
+  auto Snippet1 = R"cc(
+struct Y {
+  void m();
+};
+void z(Y y) { y.m(); }
+  )cc";
+  auto Snippet2 = R"cc(
+struct Y {
+  void m();
+};
+struct X : public Y {};
+void z(X x) { x.m(); }
+  )cc";
+  auto MatchesY = cxxMemberCallExpr(
+  onImplicitObjectArgument(hasType(cxxRecordDecl(hasName("Y");
+  EXPECT_TRUE(matches(Snippet1, MatchesY));
+  EXPECT_TRUE(matches(Snippet2, MatchesY));
+
+  auto MatchesX = cxxMemberCallExpr(
+  onImplicitObjectArgument(hasType(cxxRecordDecl(hasName("X");
+  EXPECT_TRUE(notMatches(Snippet2, MatchesX));
+
+  // Parens are not ignored.
+  auto MatchesCall = cxxMemberCallExpr(onImplicitObjectArgument(callExpr()));
+  EXPECT_TRUE(notMatches(
+  R"cc(
+struct Y {
+  void m();
+};
+Y g();
+void z(Y y) { (g()).m(); }
+  )cc",
+  MatchesCall));
+}
+
+TEST(Matcher, HasObjectExpr) {
+  auto M = 
memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X");
+  EXPECT_TRUE(matches(
+  R"cc(
+struct X {
+  int m;
+  int f(X x) { return x.m; }
+};
+  )cc",
+  M));
+  EXPECT_TRUE(notMatches(
+  R"cc(
+struct X {
+  int m;
+  int f(X x) { return m; }
+};
+  )cc",
+  M));
+}
+
 TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
   StatementMatcher ArgumentY =
 declRefExpr(to(varDecl(hasName("y".bind("arg");


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r354134 - Added test for matcher On.

2019-02-15 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Feb 15 06:43:06 2019
New Revision: 354134

URL: http://llvm.org/viewvc/llvm-project?rev=354134&view=rev
Log:
Added test for matcher On.

Modified:
cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=354134&r1=354133&r2=354134&view=diff
==
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Fri Feb 15 
06:43:06 2019
@@ -470,24 +470,26 @@ TEST(Matcher, isInstanceMessage) {
 }
 
 TEST(MatcherCXXMemberCallExpr, On) {
-  auto MatchesType = 
cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X");
-  EXPECT_TRUE(matches(
-  R"cc(
+  auto Snippet1 = R"cc(
 struct Y {
   void m();
 };
-struct X : public Y {};
-void z(X x) { x.m(); }
-  )cc",
-  MatchesType));
-  EXPECT_TRUE(notMatches(
-  R"cc(
+void z(Y y) { y.m(); }
+  )cc";
+  auto Snippet2 = R"cc(
 struct Y {
   void m();
 };
-void z(Y y) { y.m(); }
-  )cc",
-  MatchesType));
+struct X : public Y {};
+void z(X x) { x.m(); }
+  )cc";
+  auto MatchesY = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y");
+  EXPECT_TRUE(matches(Snippet1, MatchesY));
+  EXPECT_TRUE(notMatches(Snippet2, MatchesY));
+
+  auto MatchesX = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X");
+  EXPECT_TRUE(notMatches(Snippet1, MatchesX));
+  EXPECT_TRUE(matches(Snippet2, MatchesX));
 
   // Parens are ignored.
   auto MatchesCall = cxxMemberCallExpr(on(callExpr()));


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r354136 - Exteded test of .

2019-02-15 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Feb 15 06:43:10 2019
New Revision: 354136

URL: http://llvm.org/viewvc/llvm-project?rev=354136&view=rev
Log:
Exteded test of .

Modified:
cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=354136&r1=354135&r2=354136&view=diff
==
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Fri Feb 15 
06:43:10 2019
@@ -540,23 +540,27 @@ TEST(MatcherCXXMemberCallExpr, OnImplici
 }
 
 TEST(Matcher, HasObjectExpr) {
-  auto M = 
memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X");
-  EXPECT_TRUE(matches(
-  R"cc(
+  auto Snippet1 = R"cc(
 struct X {
   int m;
   int f(X x) { return x.m; }
 };
-  )cc",
-  M));
-  EXPECT_TRUE(notMatches(
-  R"cc(
+  )cc";
+  auto Snippet2 = R"cc(
 struct X {
   int m;
   int f(X x) { return m; }
 };
-  )cc",
-  M));
+  )cc";
+  auto MatchesX =
+  memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X");
+  EXPECT_TRUE(matches(Snippet1, MatchesX));
+  EXPECT_TRUE(notMatches(Snippet2, MatchesX));
+
+  auto MatchesXPointer = memberExpr(
+  hasObjectExpression(hasType(pointsTo(cxxRecordDecl(hasName("X"));
+  EXPECT_TRUE(notMatches(Snippet1, MatchesXPointer));
+  EXPECT_TRUE(matches(Snippet2, MatchesXPointer));
 }
 
 TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r354135 - Remove unnecessary expectation.

2019-02-15 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Feb 15 06:43:08 2019
New Revision: 354135

URL: http://llvm.org/viewvc/llvm-project?rev=354135&view=rev
Log:
Remove unnecessary expectation.

Modified:
cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=354135&r1=354134&r2=354135&view=diff
==
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Fri Feb 15 
06:43:08 2019
@@ -488,7 +488,6 @@ TEST(MatcherCXXMemberCallExpr, On) {
   EXPECT_TRUE(notMatches(Snippet2, MatchesY));
 
   auto MatchesX = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X");
-  EXPECT_TRUE(notMatches(Snippet1, MatchesX));
   EXPECT_TRUE(matches(Snippet2, MatchesX));
 
   // Parens are ignored.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r354136 - Exteded test of .

2019-02-15 Thread Yitzhak Mandelbaum via cfe-commits
No -- That was supposed to be a single commit. I used the git llvm push
expecting it to commit the diff that I saw through arc diff, but instead
got the four separate commits. I should have squashed the 4 (local) commits
into a single commit beforehand but missed that step.

Should rollback those commits and redo as a single one?

On Fri, Feb 15, 2019 at 9:54 AM Roman Lebedev  wrote:

> On Fri, Feb 15, 2019 at 5:42 PM Yitzhak Mandelbaum via cfe-commits
>  wrote:
> >
> > Author: ymandel
> > Date: Fri Feb 15 06:43:10 2019
> > New Revision: 354136
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=354136&view=rev
> > Log:
> > Exteded test of .
> Were last few commits were meant to be committed?
> Regardless, the commit messages could use at lot more work.
>
> > Modified:
> > cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
> >
> > Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=354136&r1=354135&r2=354136&view=diff
> >
> ==
> > --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
> (original)
> > +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Fri Feb
> 15 06:43:10 2019
> > @@ -540,23 +540,27 @@ TEST(MatcherCXXMemberCallExpr, OnImplici
> >  }
> >
> >  TEST(Matcher, HasObjectExpr) {
> > -  auto M =
> memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X");
> > -  EXPECT_TRUE(matches(
> > -  R"cc(
> > +  auto Snippet1 = R"cc(
> >  struct X {
> >int m;
> >int f(X x) { return x.m; }
> >  };
> > -  )cc",
> > -  M));
> > -  EXPECT_TRUE(notMatches(
> > -  R"cc(
> > +  )cc";
> > +  auto Snippet2 = R"cc(
> >  struct X {
> >int m;
> >int f(X x) { return m; }
> >  };
> > -  )cc",
> > -  M));
> > +  )cc";
> > +  auto MatchesX =
> > +
> memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X");
> > +  EXPECT_TRUE(matches(Snippet1, MatchesX));
> > +  EXPECT_TRUE(notMatches(Snippet2, MatchesX));
> > +
> > +  auto MatchesXPointer = memberExpr(
> > +
> hasObjectExpression(hasType(pointsTo(cxxRecordDecl(hasName("X"));
> > +  EXPECT_TRUE(notMatches(Snippet1, MatchesXPointer));
> > +  EXPECT_TRUE(matches(Snippet2, MatchesXPointer));
> >  }
> >
> >  TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
> >
> >
> > ___
> > cfe-commits mailing list
> > cfe-commits@lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D56850: [ASTMatchers][NFC] Add tests for assorted `CXXMemberCallExpr` matchers.

2019-02-15 Thread Yitzhak Mandelbaum via cfe-commits
Was it the complete diff or one of the intermediate commits? I accidentally
committed the diff as a series of commits rather than one (squashed)
commit.

On Fri, Feb 15, 2019 at 4:51 PM Martin Storsjö via Phabricator <
revi...@reviews.llvm.org> wrote:

> mstorsjo added a comment.
>
> This broke compilation with GCC 5.4 on Ubuntu 16.04:
>
>
> ../tools/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp:474:243:
> warning: missing terminating " character
>   ../tools/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp:474:3:
> error: missing terminating " character
>  EXPECT_TRUE(matches(
>  ^
>   ../tools/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp:480:7:
> error: stray ‘\’ in program
>void z(X x) { x.m(); }
>  ^
>
>
> Repository:
>   rL LLVM
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D56850/new/
>
> https://reviews.llvm.org/D56850
>
>
>
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D56933: [Tooling][RFC] Introduce Stencil library to simplify source code generation in refactorings.

2019-02-25 Thread Yitzhak Mandelbaum via cfe-commits
We're working out the details, but the intent is that the
Tree-transformation library would support the implementation of
Transformer. That is, this library is targeted at a lower-level/more
advanced user than Transformer.  Currently, Transformer is implemented
directly on the clang AST API, but we should be able to simplify it by
using this API once its ready.   Ideally, we'll hide any transition from
the user.  Conversely, we plan to expose relevant features from this API in
Transformer.

Ilya, the author of that proposal, will be the primary reviewer of the
Transformer patches, so we will be sure to keep the two proposals in
sync/complementary.

On Mon, Feb 25, 2019 at 2:58 PM Roman Lebedev via Phabricator <
revi...@reviews.llvm.org> wrote:

> lebedev.ri added subscribers: ilya-biryukov, gribozavr, lebedev.ri.
> lebedev.ri added a comment.
>
> See also:
> https://lists.llvm.org/pipermail/cfe-dev/2019-February/061414.html
> How are these two RFC's/API's supposed to interact/coexist/etc?
>
>
> Repository:
>   rG LLVM Github Monorepo
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D56933/new/
>
> https://reviews.llvm.org/D56933
>
>
>
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r362707 - [LibTooling] Add insert/remove convenience functions for creating `ASTEdit`s.

2019-06-06 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Jun  6 07:20:29 2019
New Revision: 362707

URL: http://llvm.org/viewvc/llvm-project?rev=362707&view=rev
Log:
[LibTooling] Add insert/remove convenience functions for creating `ASTEdit`s.

Summary: `change()` is an all purpose function; the revision adds simple 
shortcuts for the specific operations of inserting (before/after) or removing 
source.

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62621

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=362707&r1=362706&r2=362707&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Thu Jun  6 
07:20:29 2019
@@ -193,6 +193,23 @@ inline ASTEdit change(TextGenerator Repl
   return change(node(RewriteRule::RootID), std::move(Replacement));
 }
 
+/// Inserts \p Replacement before \p S, leaving the source selected by \S
+/// unchanged.
+inline ASTEdit insertBefore(RangeSelector S, TextGenerator Replacement) {
+  return change(before(std::move(S)), std::move(Replacement));
+}
+
+/// Inserts \p Replacement after \p S, leaving the source selected by \S
+/// unchanged.
+inline ASTEdit insertAfter(RangeSelector S, TextGenerator Replacement) {
+  return change(after(std::move(S)), std::move(Replacement));
+}
+
+/// Removes the source selected by \p S.
+inline ASTEdit remove(RangeSelector S) {
+  return change(std::move(S), text(""));
+}
+
 /// The following three functions are a low-level part of the RewriteRule
 /// API. We expose them for use in implementing the fixtures that interpret
 /// RewriteRule, like Transformer and TransfomerTidy, or for more advanced

Modified: cfe/trunk/unittests/Tooling/TransformerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/TransformerTest.cpp?rev=362707&r1=362706&r2=362707&view=diff
==
--- cfe/trunk/unittests/Tooling/TransformerTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/TransformerTest.cpp Thu Jun  6 07:20:29 2019
@@ -349,6 +349,64 @@ TEST_F(TransformerTest, NodePartMemberMu
Input, Expected);
 }
 
+TEST_F(TransformerTest, InsertBeforeEdit) {
+  std::string Input = R"cc(
+int f() {
+  return 7;
+}
+  )cc";
+  std::string Expected = R"cc(
+int f() {
+  int y = 3;
+  return 7;
+}
+  )cc";
+
+  StringRef Ret = "return";
+  testRule(makeRule(returnStmt().bind(Ret),
+insertBefore(statement(Ret), text("int y = 3;"))),
+   Input, Expected);
+}
+
+TEST_F(TransformerTest, InsertAfterEdit) {
+  std::string Input = R"cc(
+int f() {
+  int x = 5;
+  return 7;
+}
+  )cc";
+  std::string Expected = R"cc(
+int f() {
+  int x = 5;
+  int y = 3;
+  return 7;
+}
+  )cc";
+
+  StringRef Decl = "decl";
+  testRule(makeRule(declStmt().bind(Decl),
+insertAfter(statement(Decl), text("int y = 3;"))),
+   Input, Expected);
+}
+
+TEST_F(TransformerTest, RemoveEdit) {
+  std::string Input = R"cc(
+int f() {
+  int x = 5;
+  return 7;
+}
+  )cc";
+  std::string Expected = R"cc(
+int f() {
+  return 7;
+}
+  )cc";
+
+  StringRef Decl = "decl";
+  testRule(makeRule(declStmt().bind(Decl), remove(statement(Decl))), Input,
+   Expected);
+}
+
 TEST_F(TransformerTest, MultiChange) {
   std::string Input = R"cc(
 void foo() {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r363296 - [clang-tidy] Make ClangTidyCheck::OptionsView public.

2019-06-13 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Jun 13 12:05:02 2019
New Revision: 363296

URL: http://llvm.org/viewvc/llvm-project?rev=363296&view=rev
Log:
[clang-tidy] Make ClangTidyCheck::OptionsView public.

Summary: The `OptionsView` class is currently protected. This constraint 
prevents tidies from passing the OptionsView to, for example, a helper 
function. Similarly, TransformerClangTidyCheck cannot pass the `OptionsView` 
object to functions that generate `tooling::RewriteRule`s.  The latter is 
needed to allow the definition of such rules to depend on the clang-tidy 
options, as demonstrated in the child revision.

Reviewers: gribozavr

Subscribers: xazax.hun, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D63287

Modified:
clang-tools-extra/trunk/clang-tidy/ClangTidyCheck.h

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyCheck.h?rev=363296&r1=363295&r2=363296&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/ClangTidyCheck.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyCheck.h Thu Jun 13 12:05:02 2019
@@ -100,13 +100,6 @@ public:
   /// whether it has the default value or it has been overridden.
   virtual void storeOptions(ClangTidyOptions::OptionMap &Options) {}
 
-private:
-  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  StringRef getID() const override { return CheckName; }
-  std::string CheckName;
-  ClangTidyContext *Context;
-
-protected:
   /// \brief Provides access to the ``ClangTidyCheck`` options via check-local
   /// names.
   ///
@@ -181,6 +174,13 @@ protected:
 const ClangTidyOptions::OptionMap &CheckOptions;
   };
 
+private:
+  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  StringRef getID() const override { return CheckName; }
+  std::string CheckName;
+  ClangTidyContext *Context;
+
+protected:
   OptionsView Options;
   /// \brief Returns the main file name of the current translation unit.
   StringRef getCurrentMainFile() const { return Context->getCurrentFile(); }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r366469 - [LibTooling] Add function to translate and validate source range for editing

2019-07-18 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Jul 18 10:26:57 2019
New Revision: 366469

URL: http://llvm.org/viewvc/llvm-project?rev=366469&view=rev
Log:
[LibTooling] Add function to translate and validate source range for editing

Summary:
Adds the function `getRangeForEdit` to validate that a given source range is
editable and, if needed, translate it into a range in the source file (for
example, if it's sourced in macro expansions).

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64924

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h
cfe/trunk/lib/Tooling/Refactoring/SourceCode.cpp
cfe/trunk/unittests/Tooling/SourceCodeTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h?rev=366469&r1=366468&r2=366469&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/SourceCode.h Thu Jul 18 
10:26:57 2019
@@ -72,6 +72,19 @@ StringRef getExtendedText(const T &Node,
   ASTContext &Context) {
   return getText(getExtendedRange(Node, Next, Context), Context);
 }
+
+// Attempts to resolve the given range to one that can be edited by a rewrite;
+// generally, one that starts and ends within a particular file. It supports
+// a limited set of cases involving source locations in macro expansions.
+llvm::Optional
+getRangeForEdit(const CharSourceRange &EditRange, const SourceManager &SM,
+const LangOptions &LangOpts);
+
+inline llvm::Optional
+getRangeForEdit(const CharSourceRange &EditRange, const ASTContext &Context) {
+  return getRangeForEdit(EditRange, Context.getSourceManager(),
+ Context.getLangOpts());
+}
 } // namespace tooling
 } // namespace clang
 #endif // LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_H

Modified: cfe/trunk/lib/Tooling/Refactoring/SourceCode.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/SourceCode.cpp?rev=366469&r1=366468&r2=366469&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/SourceCode.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/SourceCode.cpp Thu Jul 18 10:26:57 2019
@@ -29,3 +29,37 @@ CharSourceRange clang::tooling::maybeExt
 return Range;
   return CharSourceRange::getTokenRange(Range.getBegin(), Tok->getLocation());
 }
+
+llvm::Optional
+clang::tooling::getRangeForEdit(const CharSourceRange &EditRange,
+const SourceManager &SM,
+const LangOptions &LangOpts) {
+  // FIXME: makeFileCharRange() has the disadvantage of stripping off 
"identity"
+  // macros. For example, if we're looking to rewrite the int literal 3 to 6,
+  // and we have the following definition:
+  //#define DO_NOTHING(x) x
+  // then
+  //foo(DO_NOTHING(3))
+  // will be rewritten to
+  //foo(6)
+  // rather than the arguably better
+  //foo(DO_NOTHING(6))
+  // Decide whether the current behavior is desirable and modify if not.
+  CharSourceRange Range = Lexer::makeFileCharRange(EditRange, SM, LangOpts);
+  if (Range.isInvalid())
+return None;
+
+  if (Range.getBegin().isMacroID() || Range.getEnd().isMacroID())
+return None;
+  if (SM.isInSystemHeader(Range.getBegin()) ||
+  SM.isInSystemHeader(Range.getEnd()))
+return None;
+
+  std::pair BeginInfo = 
SM.getDecomposedLoc(Range.getBegin());
+  std::pair EndInfo = SM.getDecomposedLoc(Range.getEnd());
+  if (BeginInfo.first != EndInfo.first ||
+  BeginInfo.second > EndInfo.second)
+return None;
+
+  return Range;
+}

Modified: cfe/trunk/unittests/Tooling/SourceCodeTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/SourceCodeTest.cpp?rev=366469&r1=366468&r2=366469&view=diff
==
--- cfe/trunk/unittests/Tooling/SourceCodeTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/SourceCodeTest.cpp Thu Jul 18 10:26:57 2019
@@ -6,17 +6,32 @@
 //
 
//===--===//
 
+#include "clang/Tooling/Refactoring/SourceCode.h"
 #include "TestVisitor.h"
 #include "clang/Basic/Diagnostic.h"
-#include "clang/Tooling/Refactoring/SourceCode.h"
+#include "llvm/Testing/Support/Annotations.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
+#include 
+#include 
 
 using namespace clang;
 
-using tooling::getText;
+using llvm::ValueIs;
 using tooling::getExtendedText;
+using tooling::getRangeForEdit;
+using tooling::getText;
 
 namespace {
 
+struct IntLitVisitor : TestVisitor {
+  bool VisitIntegerLiteral(IntegerLiteral *Expr) {
+OnIntLit(Expr, Context);
+return true;
+  }
+
+  std::function OnI

r366473 - [LibTooling] Relax Transformer to allow rewriting macro expansions

2019-07-18 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Jul 18 10:44:54 2019
New Revision: 366473

URL: http://llvm.org/viewvc/llvm-project?rev=366473&view=rev
Log:
[LibTooling] Relax Transformer to allow rewriting macro expansions

Summary:
Currently, Transformer rejects any changes to source locations inside macro
expansions. This change relaxes that constraint to allow rewrites when the
entirety of the expansion is replaced, since that can be mapped to replacing the
entirety of the expansion range in the file source.  This change makes
Transformer consistent with the handling of edit ranges in `clang::edit::Commit`
(which is used, for example, for applying `FixItHint`s from diagnostics).

Reviewers: ilya-biryukov

Subscribers: gribozavr, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64518

Modified:
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp?rev=366473&r1=366472&r2=366473&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp Thu Jul 18 10:44:54 2019
@@ -36,37 +36,6 @@ using llvm::StringError;
 
 using MatchResult = MatchFinder::MatchResult;
 
-// Did the text at this location originate in a macro definition (aka. body)?
-// For example,
-//
-//   #define NESTED(x) x
-//   #define MACRO(y) { int y  = NESTED(3); }
-//   if (true) MACRO(foo)
-//
-// The if statement expands to
-//
-//   if (true) { int foo = 3; }
-//   ^ ^
-//   Loc1  Loc2
-//
-// For SourceManager SM, SM.isMacroArgExpansion(Loc1) and
-// SM.isMacroArgExpansion(Loc2) are both true, but isOriginMacroBody(sm, Loc1)
-// is false, because "foo" originated in the source file (as an argument to a
-// macro), whereas isOriginMacroBody(SM, Loc2) is true, because "3" originated
-// in the definition of MACRO.
-static bool isOriginMacroBody(const clang::SourceManager &SM,
-  clang::SourceLocation Loc) {
-  while (Loc.isMacroID()) {
-if (SM.isMacroBodyExpansion(Loc))
-  return true;
-// Otherwise, it must be in an argument, so we continue searching up the
-// invocation stack. getImmediateMacroCallerLoc() gives the location of the
-// argument text, inside the call text.
-Loc = SM.getImmediateMacroCallerLoc(Loc);
-  }
-  return false;
-}
-
 Expected>
 tooling::detail::translateEdits(const MatchResult &Result,
 llvm::ArrayRef Edits) {
@@ -75,14 +44,17 @@ tooling::detail::translateEdits(const Ma
 Expected Range = Edit.TargetRange(Result);
 if (!Range)
   return Range.takeError();
-if (Range->isInvalid() ||
-isOriginMacroBody(*Result.SourceManager, Range->getBegin()))
+llvm::Optional EditRange =
+getRangeForEdit(*Range, *Result.Context);
+// FIXME: let user specify whether to treat this case as an error or ignore
+// it as is currently done.
+if (!EditRange)
   return SmallVector();
 auto Replacement = Edit.Replacement(Result);
 if (!Replacement)
   return Replacement.takeError();
 tooling::detail::Transformation T;
-T.Range = *Range;
+T.Range = *EditRange;
 T.Replacement = std::move(*Replacement);
 Transformations.push_back(std::move(T));
   }

Modified: cfe/trunk/unittests/Tooling/TransformerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/TransformerTest.cpp?rev=366473&r1=366472&r2=366473&view=diff
==
--- cfe/trunk/unittests/Tooling/TransformerTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/TransformerTest.cpp Thu Jul 18 10:44:54 2019
@@ -137,7 +137,7 @@ protected:
   TransformerTest() { appendToHeader(KHeaderContents); }
 };
 
-// Given string s, change strlen($s.c_str()) to $s.size().
+// Given string s, change strlen($s.c_str()) to REPLACED.
 static RewriteRule ruleStrlenSize() {
   StringRef StringExpr = "strexpr";
   auto StringType = namedDecl(hasAnyName("::basic_string", "::string"));
@@ -163,17 +163,6 @@ TEST_F(TransformerTest, NoMatch) {
   testRule(ruleStrlenSize(), Input, Input);
 }
 
-// Tests that expressions in macro arguments are rewritten (when applicable).
-TEST_F(TransformerTest, StrlenSizeMacro) {
-  std::string Input = R"cc(
-#define ID(e) e
-int f(string s) { return ID(strlen(s.c_str())); })cc";
-  std::string Expected = R"cc(
-#define ID(e) e
-int f(string s) { return ID(REPLACED); })cc";
-  testRule(ruleStrlenSize(), Input, Expected);
-}
-
 // Tests replacing an expression.
 TEST_F(TransformerTest, Flag) {
   StringRef Flag = "flag";
@@ -619,23 +608,114 @@ TEST_F(TransformerTest, ErrorOccurredMat
   EXPECT_EQ(ErrorCount, 0);
 }
 
-TEST_F(Transformer

r368188 - [clang][NFC] Fix typo in matcher comment

2019-08-07 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Aug  7 10:01:31 2019
New Revision: 368188

URL: http://llvm.org/viewvc/llvm-project?rev=368188&view=rev
Log:
[clang][NFC] Fix typo in matcher comment

Also updates corresponding html doc.

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=368188&r1=368187&r2=368188&view=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Wed Aug  7 10:01:31 2019
@@ -6819,7 +6819,7 @@ F& operator=(const F& o) {
 }
 returnStmt(forFunction(hasName("operator=")))
   matches 'return *this'
-  but does match 'return > 0'
+  but does not match 'return v > 0'
 
 
 

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=368188&r1=368187&r2=368188&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Wed Aug  7 10:01:31 2019
@@ -6410,7 +6410,7 @@ AST_MATCHER_FUNCTION(internal::Matcherhttps://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r368319 - [clang] Update `ignoringElidableConstructorCall` matcher to ignore `ExprWithCleanups`.

2019-08-08 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Aug  8 10:41:44 2019
New Revision: 368319

URL: http://llvm.org/viewvc/llvm-project?rev=368319&view=rev
Log:
[clang] Update `ignoringElidableConstructorCall` matcher to ignore 
`ExprWithCleanups`.

Summary:
The `ExprWithCleanups` node is added to the AST along with the elidable
CXXConstructExpr.  If it is the outermost node of the node being matched, ignore
it as well.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65944

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=368319&r1=368318&r2=368319&view=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Thu Aug  8 10:41:44 2019
@@ -5805,14 +5805,15 @@ Example matches x (matcher = expr(hasTyp
 
 MatcherExpr>ignoringElidableConstructorCallast_matchers::MatcherExpr> 
InnerMatcher
 Matches expressions that match 
InnerMatcher that are possibly wrapped in an
-elidable constructor.
+elidable constructor and other corresponding bookkeeping nodes.
 
-In C++17 copy elidable constructors are no longer being
-generated in the AST as it is not permitted by the standard. They are
-however part of the AST in C++14 and earlier. Therefore, to write a matcher
-that works in all language modes, the matcher has to skip elidable
-constructor AST nodes if they appear in the AST. This matcher can be used to
-skip those elidable constructors.
+In C++17, elidable copy constructors are no longer being generated in the
+AST as it is not permitted by the standard. They are, however, part of the
+AST in C++14 and earlier. So, a matcher must abstract over these differences
+to work in all language modes. This matcher skips elidable constructor-call
+AST nodes, `ExprWithCleanups` nodes wrapping elidable constructor-calls and
+various implicit nodes inside the constructor calls, all of which will not
+appear in the C++17 AST.
 
 Given
 
@@ -5822,10 +5823,8 @@ void f() {
   H D = G();
 }
 
-``varDecl(hasInitializer(any(
-  ignoringElidableConstructorCall(callExpr()),
-  exprWithCleanups(ignoringElidableConstructorCall(callExpr()``
-matches ``H D = G()``
+``varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr(``
+matches ``H D = G()`` in C++11 through C++17 (and beyond).
 
 
 

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=368319&r1=368318&r2=368319&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Thu Aug  8 10:41:44 2019
@@ -6533,14 +6533,15 @@ AST_MATCHER(FunctionDecl, hasTrailingRet
 }
 
 /// Matches expressions that match InnerMatcher that are possibly wrapped in an
-/// elidable constructor.
+/// elidable constructor and other corresponding bookkeeping nodes.
 ///
-/// In C++17 copy elidable constructors are no longer being
-/// generated in the AST as it is not permitted by the standard. They are
-/// however part of the AST in C++14 and earlier. Therefore, to write a matcher
-/// that works in all language modes, the matcher has to skip elidable
-/// constructor AST nodes if they appear in the AST. This matcher can be used 
to
-/// skip those elidable constructors.
+/// In C++17, elidable copy constructors are no longer being generated in the
+/// AST as it is not permitted by the standard. They are, however, part of the
+/// AST in C++14 and earlier. So, a matcher must abstract over these 
differences
+/// to work in all language modes. This matcher skips elidable constructor-call
+/// AST nodes, `ExprWithCleanups` nodes wrapping elidable constructor-calls and
+/// various implicit nodes inside the constructor calls, all of which will not
+/// appear in the C++17 AST.
 ///
 /// Given
 ///
@@ -6552,13 +6553,20 @@ AST_MATCHER(FunctionDecl, hasTrailingRet
 /// }
 /// \endcode
 ///
-/// ``varDecl(hasInitializer(any(
-///   ignoringElidableConstructorCall(callExpr()),
-///   exprWithCleanups(ignoringElidableConstructorCall(callExpr()``
-/// matches ``H D = G()``
+/// ``varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr(``
+/// matches ``H D = G()`` in C++11 through C++17 (and beyond).
 AST_MATCHER_P(Expr, ignoringElidableConstructorCall,
   ast_matchers::internal::Matcher, InnerMatcher) {
-  if (const auto *CtorExpr = dyn_cast(&Node)) {
+  // E trac

r368326 - [clang][NFC] Move matcher ignoringElidableConstructorCall's tests to appropriate file.

2019-08-08 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Aug  8 11:55:42 2019
New Revision: 368326

URL: http://llvm.org/viewvc/llvm-project?rev=368326&view=rev
Log:
[clang][NFC] Move matcher ignoringElidableConstructorCall's tests to 
appropriate file.

Summary:
`ignoringElidableConstructorCall` is a traversal matcher, but its tests are
grouped with narrowing-matcher tests. This revision moves them to the correct
file.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65963

Modified:
cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp?rev=368326&r1=368325&r2=368326&view=diff
==
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Thu Aug  8 
11:55:42 2019
@@ -603,91 +603,6 @@ TEST(Matcher, BindMatchedNodes) {

llvm::make_unique>("x")));
 }
 
-TEST(Matcher, IgnoresElidableConstructors) {
-  EXPECT_TRUE(
-  matches("struct H {};"
-  "template H B(T A);"
-  "void f() {"
-  "  H D1;"
-  "  D1 = B(B(1));"
-  "}",
-  cxxOperatorCallExpr(hasArgument(
-  1, callExpr(hasArgument(
- 0, ignoringElidableConstructorCall(callExpr()),
-  LanguageMode::Cxx11OrLater));
-  EXPECT_TRUE(
-  matches("struct H {};"
-  "template H B(T A);"
-  "void f() {"
-  "  H D1;"
-  "  D1 = B(1);"
-  "}",
-  cxxOperatorCallExpr(hasArgument(
-  1, callExpr(hasArgument(0, ignoringElidableConstructorCall(
- integerLiteral()),
-  LanguageMode::Cxx11OrLater));
-  EXPECT_TRUE(matches(
-  "struct H {};"
-  "H G();"
-  "void f() {"
-  "  H D = G();"
-  "}",
-  varDecl(hasInitializer(anyOf(
-  ignoringElidableConstructorCall(callExpr()),
-  
exprWithCleanups(has(ignoringElidableConstructorCall(callExpr())),
-  LanguageMode::Cxx11OrLater));
-}
-
-TEST(Matcher, IgnoresElidableInReturn) {
-  auto matcher = expr(ignoringElidableConstructorCall(declRefExpr()));
-  EXPECT_TRUE(matches("struct H {};"
-  "H f() {"
-  "  H g;"
-  "  return g;"
-  "}",
-  matcher, LanguageMode::Cxx11OrLater));
-  EXPECT_TRUE(notMatches("struct H {};"
- "H f() {"
- "  return H();"
- "}",
- matcher, LanguageMode::Cxx11OrLater));
-}
-
-TEST(Matcher, IgnoreElidableConstructorDoesNotMatchConstructors) {
-  EXPECT_TRUE(matches("struct H {};"
-  "void f() {"
-  "  H D;"
-  "}",
-  varDecl(hasInitializer(
-  
ignoringElidableConstructorCall(cxxConstructExpr(,
-  LanguageMode::Cxx11OrLater));
-}
-
-TEST(Matcher, IgnoresElidableDoesNotPreventMatches) {
-  EXPECT_TRUE(matches("void f() {"
-  "  int D = 10;"
-  "}",
-  expr(ignoringElidableConstructorCall(integerLiteral())),
-  LanguageMode::Cxx11OrLater));
-}
-
-TEST(Matcher, IgnoresElidableInVarInit) {
-  auto matcher =
-  varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr(;
-  EXPECT_TRUE(matches("struct H {};"
-  "H G();"
-  "void f(H D = G()) {"
-  "  return;"
-  "}",
-  matcher, LanguageMode::Cxx11OrLater));
-  EXPECT_TRUE(matches("struct H {};"
-  "H G();"
-  "void f() {"
-  "  H D = G();"
-  "}",
-  matcher, LanguageMode::Cxx11OrLater));
-}
-
 TEST(Matcher, BindTheSameNameInAlternatives) {
   StatementMatcher matcher = anyOf(
 binaryOperator(hasOperatorName("+"),

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=368326&r1=368325&r2=368326&view=diff
==
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Thu Aug  8 
11:55:42 2019
@@ -1461,6 +1461,91 @@ TEST(HasImplicitDestinationType, DoesNot

r368681 - [libTooling] In Transformer, generalize `applyFirst` to admit rules with incompatible matchers.

2019-08-13 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Tue Aug 13 05:31:29 2019
New Revision: 368681

URL: http://llvm.org/viewvc/llvm-project?rev=368681&view=rev
Log:
[libTooling] In Transformer, generalize `applyFirst` to admit rules with 
incompatible matchers.

Summary:
This patch removes an (artificial) limitation of `applyFirst`, which requires
that all of the rules' matchers can be grouped together in a single `anyOf()`.
This change generalizes the code to group the matchers into separate `anyOf`s
based on compatibility. Correspondingly, `buildMatcher` is changed to
`buildMatchers`, to allow for returning a set of matchers rather than just one.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65877

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=368681&r1=368680&r2=368681&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Tue Aug 13 
05:31:29 2019
@@ -160,11 +160,9 @@ inline RewriteRule makeRule(ast_matchers
 void addInclude(RewriteRule &Rule, llvm::StringRef Header,
 IncludeFormat Format = IncludeFormat::Quoted);
 
-/// Applies the first rule whose pattern matches; other rules are ignored.
-///
-/// N.B. All of the rules must use the same kind of matcher (that is, share a
-/// base class in the AST hierarchy).  However, this constraint is caused by an
-/// implementation detail and should be lifted in the future.
+/// Applies the first rule whose pattern matches; other rules are ignored.  If
+/// the matchers are independent then order doesn't matter. In that case,
+/// `applyFirst` is simply joining the set of rules into one.
 //
 // `applyFirst` is like an `anyOf` matcher with an edit action attached to each
 // of its cases. Anywhere you'd use `anyOf(m1.bind("id1"), m2.bind("id2"))` and
@@ -243,8 +241,19 @@ inline ASTEdit remove(RangeSelector S) {
 // public and well-supported and move them out of `detail`.
 namespace detail {
 /// Builds a single matcher for the rule, covering all of the rule's cases.
+/// Only supports Rules whose cases' matchers share the same base "kind"
+/// (`Stmt`, `Decl`, etc.)  Deprecated: use `buildMatchers` instead, which
+/// supports mixing matchers of different kinds.
 ast_matchers::internal::DynTypedMatcher buildMatcher(const RewriteRule &Rule);
 
+/// Builds a set of matchers that cover the rule (one for each distinct node
+/// matcher base kind: Stmt, Decl, etc.). Node-matchers for `QualType` and
+/// `Type` are not permitted, since such nodes carry no source location
+/// information and are therefore not relevant for rewriting. If any such
+/// matchers are included, will return an empty vector.
+std::vector
+buildMatchers(const RewriteRule &Rule);
+
 /// Returns the \c Case of \c Rule that was selected in the match result.
 /// Assumes a matcher built with \c buildMatcher.
 const RewriteRule::Case &

Modified: cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp?rev=368681&r1=368680&r2=368681&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp Tue Aug 13 05:31:29 2019
@@ -19,10 +19,10 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
-#include 
 #include 
 #include 
 #include 
+#include 
 
 using namespace clang;
 using namespace tooling;
@@ -80,52 +80,23 @@ void tooling::addInclude(RewriteRule &Ru
 Case.AddedIncludes.emplace_back(Header.str(), Format);
 }
 
-// Determines whether A is a base type of B in the class hierarchy, including
-// the implicit relationship of Type and QualType.
-static bool isBaseOf(ASTNodeKind A, ASTNodeKind B) {
-  static auto TypeKind = ASTNodeKind::getFromNodeKind();
-  static auto QualKind = ASTNodeKind::getFromNodeKind();
-  /// Mimic the implicit conversions of Matcher<>.
-  /// - From Matcher to Matcher
-  /// - From Matcher to Matcher
-  return (A.isSame(TypeKind) && B.isSame(QualKind)) || A.isBaseOf(B);
-}
-
-// Try to find a common kind to which all of the rule's matchers can be
-// converted.
-static ASTNodeKind
-findCommonKind(const SmallVectorImpl &Cases) {
-  assert(!Cases.empty() && "Rule must have at least one case.");
-  ASTNodeKind JoinKind = Cases[0].Matcher.getSupportedKind();
-  // Find a (least) Kind K, for which M.canConvertTo(K) holds, for all matchers
-  // M in Rules.
-  for (const auto &Case : Cases

[clang-tools-extra] r368700 - [clang-tidy] Update `TransformerClangTidyCheck` to use new `buildMatchers` functionality.

2019-08-13 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Tue Aug 13 07:48:13 2019
New Revision: 368700

URL: http://llvm.org/viewvc/llvm-project?rev=368700&view=rev
Log:
[clang-tidy] Update `TransformerClangTidyCheck` to use new `buildMatchers` 
functionality.

Summary:
`buildMatchers` is the new, more general way to extract the matcher from a rule.
This change migrates the code to use it instead of `buildMatcher`.

Reviewers: gribozavr

Subscribers: xazax.hun, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65879

Modified:
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp?rev=368700&r1=368699&r2=368700&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp Tue 
Aug 13 07:48:13 2019
@@ -62,7 +62,8 @@ void TransformerClangTidyCheck::register
 void TransformerClangTidyCheck::registerMatchers(
 ast_matchers::MatchFinder *Finder) {
   if (Rule)
-Finder->addDynamicMatcher(tooling::detail::buildMatcher(*Rule), this);
+for (auto &Matcher : tooling::detail::buildMatchers(*Rule))
+  Finder->addDynamicMatcher(Matcher, this);
 }
 
 void TransformerClangTidyCheck::check(


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r368862 - [libTooling] Fix code to avoid unused-function warning after r368681.

2019-08-14 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Aug 14 08:20:06 2019
New Revision: 368862

URL: http://llvm.org/viewvc/llvm-project?rev=368862&view=rev
Log:
[libTooling] Fix code to avoid unused-function warning after r368681.

Modified:
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp

Modified: cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp?rev=368862&r1=368861&r2=368862&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp Wed Aug 14 08:20:06 2019
@@ -80,12 +80,14 @@ void tooling::addInclude(RewriteRule &Ru
 Case.AddedIncludes.emplace_back(Header.str(), Format);
 }
 
+#ifndef NDEBUG
 // Filters for supported matcher kinds. FIXME: Explicitly list the allowed 
kinds
 // (all node matcher types except for `QualType` and `Type`), rather than just
 // banning `QualType` and `Type`.
 static bool hasValidKind(const DynTypedMatcher &M) {
   return !M.canConvertTo();
 }
+#endif
 
 // Binds each rule's matcher to a unique (and deterministic) tag based on
 // `TagBase` and the id paired with the case.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r364435 - [clang-tidy] Fix ClangTidyTest to initialize context before checks.

2019-06-26 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Jun 26 08:04:33 2019
New Revision: 364435

URL: http://llvm.org/viewvc/llvm-project?rev=364435&view=rev
Log:
[clang-tidy] Fix ClangTidyTest to initialize context before checks.

Summary:
Currently, `clang::tidy::test::runCheckOnCode()` constructs the check
instances *before* initializing the ClangTidyContext. This ordering causes
problems when the check's constructor accesses the context, for example, through
`getLangOpts()`.

This revision moves the construction to after the context initialization, which
follows the pattern used in the clang tidy tool itself.

Reviewers: gribozavr

Subscribers: xazax.hun, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D63784

Modified:
clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h

Modified: clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h?rev=364435&r1=364434&r2=364435&view=diff
==
--- clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h (original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h Wed Jun 26 
08:04:33 2019
@@ -27,6 +27,25 @@ namespace clang {
 namespace tidy {
 namespace test {
 
+template  struct CheckFactory {
+  static void
+  createChecks(ClangTidyContext *Context,
+   SmallVectorImpl> &Result) {
+CheckFactory::createChecks(Context, Result);
+CheckFactory::createChecks(Context, Result);
+  }
+};
+
+template  struct CheckFactory {
+  static void
+  createChecks(ClangTidyContext *Context,
+   SmallVectorImpl> &Result) {
+Result.emplace_back(llvm::make_unique(
+"test-check-" + std::to_string(Result.size()), Context));
+  }
+};
+
+template 
 class TestClangTidyAction : public ASTFrontendAction {
 public:
   TestClangTidyAction(SmallVectorImpl> &Checks,
@@ -42,6 +61,11 @@ private:
 Context.setASTContext(&Compiler.getASTContext());
 
 Preprocessor *PP = &Compiler.getPreprocessor();
+
+// Checks must be created here, _after_ `Context` has been initialized, so
+// that check constructors can access the context (for example, through
+// `getLangOpts()`).
+CheckFactory::createChecks(&Context, Checks);
 for (auto &Check : Checks) {
   Check->registerMatchers(&Finder);
   Check->registerPPCallbacks(Compiler.getSourceManager(), PP, PP);
@@ -54,25 +78,7 @@ private:
   ClangTidyContext &Context;
 };
 
-template  struct CheckFactory {
-  static void
-  createChecks(ClangTidyContext *Context,
-   SmallVectorImpl> &Result) {
-CheckFactory::createChecks(Context, Result);
-CheckFactory::createChecks(Context, Result);
-  }
-};
-
-template  struct CheckFactory {
-  static void
-  createChecks(ClangTidyContext *Context,
-   SmallVectorImpl> &Result) {
-Result.emplace_back(llvm::make_unique(
-"test-check-" + std::to_string(Result.size()), Context));
-  }
-};
-
-template 
+template 
 std::string
 runCheckOnCode(StringRef Code, std::vector *Errors = nullptr,
const Twine &Filename = "input.cc",
@@ -110,9 +116,9 @@ runCheckOnCode(StringRef Code, std::vect
   new FileManager(FileSystemOptions(), InMemoryFileSystem));
 
   SmallVector, 1> Checks;
-  CheckFactory::createChecks(&Context, Checks);
   tooling::ToolInvocation Invocation(
-  Args, new TestClangTidyAction(Checks, Finder, Context), Files.get());
+  Args, new TestClangTidyAction(Checks, Finder, Context),
+  Files.get());
   InMemoryFileSystem->addFile(Filename, 0,
   llvm::MemoryBuffer::getMemBuffer(Code));
   for (const auto &FileContent : PathsToContent) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r364442 - [clang-tidy] Generalize TransformerClangTidyCheck to take a rule generator.

2019-06-26 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Jun 26 09:04:38 2019
New Revision: 364442

URL: http://llvm.org/viewvc/llvm-project?rev=364442&view=rev
Log:
[clang-tidy] Generalize TransformerClangTidyCheck to take a rule generator.

Summary: Tidy check behavior often depends on language and/or clang-tidy 
options. This revision allows a user of TranformerClangTidyCheck to pass rule 
_generator_ in place of a rule, where the generator takes both the language and 
clang-tidy options. Additionally, the generator returns an `Optional` to allow 
for the case where the check is deemed irrelevant/disable based on those 
options.

Reviewers: gribozavr

Subscribers: xazax.hun, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D63288

Modified:
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h

clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp?rev=364442&r1=364441&r2=364442&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp Wed 
Jun 26 09:04:38 2019
@@ -14,20 +14,40 @@ namespace tidy {
 namespace utils {
 using tooling::RewriteRule;
 
+static bool hasExplanation(const RewriteRule::Case &C) {
+  return C.Explanation != nullptr;
+}
+
+// This constructor cannot dispatch to the simpler one (below), because, in
+// order to get meaningful results from `getLangOpts` and `Options`, we need 
the
+// `ClangTidyCheck()` constructor to have been called. If we were to dispatch,
+// we would be accessing `getLangOpts` and `Options` before the underlying
+// `ClangTidyCheck` instance was properly initialized.
+TransformerClangTidyCheck::TransformerClangTidyCheck(
+std::function(const LangOptions &,
+const OptionsView &)>
+MakeRule,
+StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context), Rule(MakeRule(getLangOpts(), Options)) {
+  if (Rule)
+assert(llvm::all_of(Rule->Cases, hasExplanation) &&
+   "clang-tidy checks must have an explanation by default;"
+   " explicitly provide an empty explanation if none is desired");
+}
+
 TransformerClangTidyCheck::TransformerClangTidyCheck(RewriteRule R,
  StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context), Rule(std::move(R)) {
-  assert(llvm::all_of(Rule.Cases, [](const RewriteRule::Case &C) {
-   return C.Explanation != nullptr;
- }) &&
+  assert(llvm::all_of(Rule->Cases, hasExplanation) &&
  "clang-tidy checks must have an explanation by default;"
  " explicitly provide an empty explanation if none is desired");
 }
 
 void TransformerClangTidyCheck::registerMatchers(
 ast_matchers::MatchFinder *Finder) {
-  Finder->addDynamicMatcher(tooling::detail::buildMatcher(Rule), this);
+  if (Rule)
+Finder->addDynamicMatcher(tooling::detail::buildMatcher(*Rule), this);
 }
 
 void TransformerClangTidyCheck::check(
@@ -43,7 +63,8 @@ void TransformerClangTidyCheck::check(
   Root->second.getSourceRange().getBegin());
   assert(RootLoc.isValid() && "Invalid location for Root node of match.");
 
-  RewriteRule::Case Case = tooling::detail::findSelectedCase(Result, Rule);
+  assert(Rule && "check() should not fire if Rule is None");
+  RewriteRule::Case Case = tooling::detail::findSelectedCase(Result, *Rule);
   Expected> Transformations =
   tooling::detail::translateEdits(Result, Case.Edits);
   if (!Transformations) {

Modified: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h?rev=364442&r1=364441&r2=364442&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h 
(original)
+++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h Wed 
Jun 26 09:04:38 2019
@@ -31,19 +31,32 @@ namespace utils {
 // };
 class TransformerClangTidyCheck : public ClangTidyCheck {
 public:
-  // All cases in \p R must have a non-null \c Explanation, even though \c
-  // Explanation is optional for RewriteRule in general. Because the primary
-  // purpose of clang-tidy checks is to provide users with diagnostics, we
-  // assume that a missing explanation is a bug.  If no explanation is desired,
-  // indicate that explicitly (for example, by passing `text

r364917 - [LibTooling] Extend `RewriteRule` with support for adding includes.

2019-07-02 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Tue Jul  2 06:11:04 2019
New Revision: 364917

URL: http://llvm.org/viewvc/llvm-project?rev=364917&view=rev
Log:
[LibTooling] Extend `RewriteRule` with support for adding includes.

Summary:
This revision allows users to specify the insertion of an included directive (at
the top of the file being rewritten) as part of a rewrite rule.  These
directives are bundled with `RewriteRule` cases, so that different cases can
potentially result in different include actions.

Reviewers: ilya-biryukov, gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D63892

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=364917&r1=364916&r2=364917&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Tue Jul  2 
06:11:04 2019
@@ -86,6 +86,12 @@ struct ASTEdit {
   TextGenerator Note;
 };
 
+/// Format of the path in an include directive -- angle brackets or quotes.
+enum class IncludeFormat {
+  Quoted,
+  Angled,
+};
+
 /// Description of a source-code transformation.
 //
 // A *rewrite rule* describes a transformation of source code. A simple rule
@@ -114,6 +120,10 @@ struct RewriteRule {
 ast_matchers::internal::DynTypedMatcher Matcher;
 SmallVector Edits;
 TextGenerator Explanation;
+// Include paths to add to the file affected by this case.  These are
+// bundled with the `Case`, rather than the `RewriteRule`, because each 
case
+// might have different associated changes to the includes.
+std::vector> AddedIncludes;
   };
   // We expect RewriteRules will most commonly include only one case.
   SmallVector Cases;
@@ -137,6 +147,19 @@ inline RewriteRule makeRule(ast_matchers
   return makeRule(std::move(M), std::move(Edits), std::move(Explanation));
 }
 
+/// For every case in Rule, adds an include directive for the given header. The
+/// common use is assumed to be a rule with only one case. For example, to
+/// replace a function call and add headers corresponding to the new code, one
+/// could write:
+/// \code
+///   auto R = makeRule(callExpr(callee(functionDecl(hasName("foo",
+///change(text("bar()")));
+///   AddInclude(R, "path/to/bar_header.h");
+///   AddInclude(R, "vector", IncludeFormat::Angled);
+/// \endcode
+void addInclude(RewriteRule &Rule, llvm::StringRef Header,
+IncludeFormat Format = IncludeFormat::Quoted);
+
 /// Applies the first rule whose pattern matches; other rules are ignored.
 ///
 /// N.B. All of the rules must use the same kind of matcher (that is, share a

Modified: cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp?rev=364917&r1=364916&r2=364917&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp Tue Jul  2 06:11:04 2019
@@ -98,8 +98,14 @@ ASTEdit tooling::change(RangeSelector S,
 
 RewriteRule tooling::makeRule(DynTypedMatcher M, SmallVector Edits,
   TextGenerator Explanation) {
-  return RewriteRule{{RewriteRule::Case{std::move(M), std::move(Edits),
-std::move(Explanation)}}};
+  return RewriteRule{{RewriteRule::Case{
+  std::move(M), std::move(Edits), std::move(Explanation), {;
+}
+
+void tooling::addInclude(RewriteRule &Rule, StringRef Header,
+ IncludeFormat Format) {
+  for (auto &Case : Rule.Cases)
+Case.AddedIncludes.emplace_back(Header.str(), Format);
 }
 
 // Determines whether A is a base type of B in the class hierarchy, including
@@ -217,8 +223,8 @@ void Transformer::run(const MatchResult
   Root->second.getSourceRange().getBegin());
   assert(RootLoc.isValid() && "Invalid location for Root node of match.");
 
-  auto Transformations = tooling::detail::translateEdits(
-  Result, tooling::detail::findSelectedCase(Result, Rule).Edits);
+  RewriteRule::Case Case = tooling::detail::findSelectedCase(Result, Rule);
+  auto Transformations = tooling::detail::translateEdits(Result, Case.Edits);
   if (!Transformations) {
 Consumer(Transformations.takeError());
 return;
@@ -241,5 +247,17 @@ void Transformer::run(const MatchResult
 }
   }
 
+  for (const auto &I : Case.AddedIncludes) {
+auto &Header = I.first;
+switch (I.second) {
+  case IncludeFormat::Quoted:
+AC.addHeader(Header);
+break;
+  case Inc

[clang-tools-extra] r364922 - [clang-tidy] Extend TransformerClangTidyCheck to support adding includes.

2019-07-02 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Tue Jul  2 06:25:07 2019
New Revision: 364922

URL: http://llvm.org/viewvc/llvm-project?rev=364922&view=rev
Log:
[clang-tidy] Extend TransformerClangTidyCheck to support adding includes.

Summary:
This revision implements support for the `AddedIncludes` field in
RewriteRule cases; that is, it supports specifying the addition of include
directives in files modified by the clang tidy check.

Reviewers: ilya-biryukov, gribozavr

Subscribers: xazax.hun, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D63893

Modified:
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h

clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp?rev=364922&r1=364921&r2=364922&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp Tue 
Jul  2 06:25:07 2019
@@ -46,6 +46,19 @@ TransformerClangTidyCheck::TransformerCl
  " explicitly provide an empty explanation if none is desired");
 }
 
+void TransformerClangTidyCheck::registerPPCallbacks(
+const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) 
{
+  // Only allocate and register the IncludeInsert when some `Case` will add
+  // includes.
+  if (Rule && llvm::any_of(Rule->Cases, [](const RewriteRule::Case &C) {
+return !C.AddedIncludes.empty();
+  })) {
+Inserter = llvm::make_unique(
+SM, getLangOpts(), utils::IncludeSorter::IS_LLVM);
+PP->addPPCallbacks(Inserter->CreatePPCallbacks());
+  }
+}
+
 void TransformerClangTidyCheck::registerMatchers(
 ast_matchers::MatchFinder *Finder) {
   if (Rule)
@@ -89,6 +102,15 @@ void TransformerClangTidyCheck::check(
   for (const auto &T : *Transformations) {
 Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
   }
+
+  for (const auto &I : Case.AddedIncludes) {
+auto &Header = I.first;
+if (Optional Fix = Inserter->CreateIncludeInsertion(
+Result.SourceManager->getMainFileID(), Header,
+/*IsAngled=*/I.second == tooling::IncludeFormat::Angled)) {
+  Diag << *Fix;
+}
+  }
 }
 
 } // namespace utils

Modified: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h?rev=364922&r1=364921&r2=364922&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h 
(original)
+++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h Tue 
Jul  2 06:25:07 2019
@@ -10,7 +10,9 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_TRANSFORMER_CLANG_TIDY_CHECK_H
 
 #include "../ClangTidy.h"
+#include "../utils/IncludeInserter.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Frontend/CompilerInstance.h"
 #include "clang/Tooling/Refactoring/Transformer.h"
 #include 
 #include 
@@ -52,11 +54,14 @@ public:
   TransformerClangTidyCheck(tooling::RewriteRule R, StringRef Name,
 ClangTidyContext *Context);
 
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+   Preprocessor *ModuleExpanderPP) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) final;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
 
 private:
   Optional Rule;
+  std::unique_ptr Inserter;
 };
 
 } // namespace utils

Modified: 
clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp?rev=364922&r1=364921&r2=364922&view=diff
==
--- 
clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp 
(original)
+++ 
clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp 
Tue Jul  2 06:25:07 2019
@@ -19,6 +19,7 @@ namespace tidy {
 namespace utils {
 namespace {
 using tooling::change;
+using tooling::IncludeFormat;
 using tooling::RewriteRule;
 using tooling::text;
 using tooling::stencil::cat;
@@ -121,6 +122,54 @@ TEST(TransformerClangTidyCheckTest, Disa
   Input, nullptr, "input.cc", None, Options));
 }
 
+RewriteRule replaceCall(IncludeFormat Format) {
+  using namespace ::clang::ast_matchers;
+  RewriteRule Rule = makeRule(callExpr(callee(functionDecl(hasName("f",
+  

r361037 - [LibTooling] Add support to Transformer for composing rules as an ordered choice.

2019-05-17 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri May 17 07:23:33 2019
New Revision: 361037

URL: http://llvm.org/viewvc/llvm-project?rev=361037&view=rev
Log:
[LibTooling] Add support to Transformer for composing rules as an ordered 
choice.

This revision updates `RewriteRule` to support multiple subrules that are
interpreted as an ordered-choice (apply the first one that matches). With this
feature, users can write the rules that appear later in the list of subrules
knowing that previous rules' patterns *have not matched*, freeing them from
reasoning about those cases in the current pattern.

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D61335

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=361037&r1=361036&r2=361037&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Fri May 17 
07:23:33 2019
@@ -145,8 +145,8 @@ template  ASTEdit change(std
 
 /// Description of a source-code transformation.
 //
-// A *rewrite rule* describes a transformation of source code. It has the
-// following components:
+// A *rewrite rule* describes a transformation of source code. A simple rule
+// contains each of the following components:
 //
 // * Matcher: the pattern term, expressed as clang matchers (with Transformer
 //   extensions).
@@ -156,30 +156,31 @@ template  ASTEdit change(std
 // * Explanation: explanation of the rewrite.  This will be displayed to the
 //   user, where possible; for example, in clang-tidy diagnostics.
 //
-// Rules have an additional, implicit, component: the parameters. These are
-// portions of the pattern which are left unspecified, yet named so that we can
-// reference them in the replacement term.  The structure of parameters can be
-// partially or even fully specified, in which case they serve just to identify
-// matched nodes for later reference rather than abstract over portions of the
-// AST.  However, in all cases, we refer to named portions of the pattern as
-// parameters.
+// However, rules can also consist of (sub)rules, where the first that matches
+// is applied and the rest are ignored.  So, the above components are gathered
+// as a `Case` and a rule is a list of cases.
+//
+// Rule cases have an additional, implicit, component: the parameters. These 
are
+// portions of the pattern which are left unspecified, yet bound in the pattern
+// so that we can reference them in the edits.
 //
-// The \c Transformer class should be used to apply the rewrite rule and obtain
-// the corresponding replacements.
+// The \c Transformer class can be used to apply the rewrite rule and obtain 
the
+// corresponding replacements.
 struct RewriteRule {
-  // `Matcher` describes the context of this rule. It should always be bound to
-  // at least `RootId`.
-  ast_matchers::internal::DynTypedMatcher Matcher;
-  SmallVector Edits;
-  TextGenerator Explanation;
+  struct Case {
+ast_matchers::internal::DynTypedMatcher Matcher;
+SmallVector Edits;
+TextGenerator Explanation;
+  };
+  // We expect RewriteRules will most commonly include only one case.
+  SmallVector Cases;
 
   // Id used as the default target of each match. The node described by the
   // matcher is should always be bound to this id.
   static constexpr llvm::StringLiteral RootId = "___root___";
 };
 
-/// Convenience function for constructing a \c RewriteRule. Takes care of
-/// binding the matcher to RootId.
+/// Convenience function for constructing a simple \c RewriteRule.
 RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
  SmallVector Edits);
 
@@ -191,12 +192,73 @@ inline RewriteRule makeRule(ast_matchers
   return makeRule(std::move(M), std::move(Edits));
 }
 
+/// Applies the first rule whose pattern matches; other rules are ignored.
+///
+/// N.B. All of the rules must use the same kind of matcher (that is, share a
+/// base class in the AST hierarchy).  However, this constraint is caused by an
+/// implementation detail and should be lifted in the future.
+//
+// `applyFirst` is like an `anyOf` matcher with an edit action attached to each
+// of its cases. Anywhere you'd use `anyOf(m1.bind("id1"), m2.bind("id2"))` and
+// then dispatch on those ids in your code for control flow, `applyFirst` lifts
+// that behavior to the rule level.  So, you can write 
`applyFirst({makeRule(m1,
+// action1), makeRule(m2, action2), ...});`
+//
+// For example, consider a type `T` with a deterministic serialization 
function,
+// `serialize()`.  For performance reasons, we would

Re: r361033 - Add a Visit overload for DynTypedNode to ASTNodeTraverser

2019-05-17 Thread Yitzhak Mandelbaum via cfe-commits
Looks like this caused a breakage:
http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/18641/steps/ninja%20check%201/logs/stdio

On Fri, May 17, 2019 at 9:52 AM Stephen Kelly via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Author: steveire
> Date: Fri May 17 06:55:28 2019
> New Revision: 361033
>
> URL: http://llvm.org/viewvc/llvm-project?rev=361033&view=rev
> Log:
> Add a Visit overload for DynTypedNode to ASTNodeTraverser
>
> Reviewers: aaron.ballman
>
> Subscribers: cfe-commits
>
> Tags: #clang
>
> Differential Revision: https://reviews.llvm.org/D61834
>
> Added:
> cfe/trunk/unittests/AST/ASTTraverserTest.cpp
> Modified:
> cfe/trunk/include/clang/AST/ASTNodeTraverser.h
> cfe/trunk/unittests/AST/CMakeLists.txt
>
> Modified: cfe/trunk/include/clang/AST/ASTNodeTraverser.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=361033&r1=361032&r2=361033&view=diff
>
> ==
> --- cfe/trunk/include/clang/AST/ASTNodeTraverser.h (original)
> +++ cfe/trunk/include/clang/AST/ASTNodeTraverser.h Fri May 17 06:55:28 2019
> @@ -205,6 +205,24 @@ public:
>  });
>}
>
> +  void Visit(const ast_type_traits::DynTypedNode &N) {
> +// FIXME: Improve this with a switch or a visitor pattern.
> +if (const auto *D = N.get())
> +  Visit(D);
> +else if (const auto *S = N.get())
> +  Visit(S);
> +else if (const auto *QT = N.get())
> +  Visit(*QT);
> +else if (const auto *T = N.get())
> +  Visit(T);
> +else if (const auto *C = N.get())
> +  Visit(C);
> +else if (const auto *C = N.get())
> +  Visit(C);
> +else if (const auto *T = N.get())
> +  Visit(*T);
> +  }
> +
>void dumpDeclContext(const DeclContext *DC) {
>  if (!DC)
>return;
>
> Added: cfe/trunk/unittests/AST/ASTTraverserTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTTraverserTest.cpp?rev=361033&view=auto
>
> ==
> --- cfe/trunk/unittests/AST/ASTTraverserTest.cpp (added)
> +++ cfe/trunk/unittests/AST/ASTTraverserTest.cpp Fri May 17 06:55:28 2019
> @@ -0,0 +1,220 @@
> +//===-
> unittests/AST/ASTTraverserTest.h===//
> +//
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
> +// See https://llvm.org/LICENSE.txt for license information.
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> +//
>
> +//===--===//
> +
> +#include "clang/AST/ASTContext.h"
> +#include "clang/AST/ASTNodeTraverser.h"
> +#include "clang/AST/TextNodeDumper.h"
> +#include "clang/ASTMatchers/ASTMatchFinder.h"
> +#include "clang/ASTMatchers/ASTMatchers.h"
> +#include "clang/Tooling/Tooling.h"
> +#include "gmock/gmock.h"
> +#include "gtest/gtest.h"
> +
> +using namespace clang::tooling;
> +using namespace clang::ast_matchers;
> +
> +namespace clang {
> +
> +class NodeTreePrinter : public TextTreeStructure {
> +  llvm::raw_ostream &OS;
> +
> +public:
> +  NodeTreePrinter(llvm::raw_ostream &OS)
> +  : TextTreeStructure(OS, /* showColors */ false), OS(OS) {}
> +
> +  void Visit(const Decl *D) { OS << D->getDeclKindName() << "Decl"; }
> +
> +  void Visit(const Stmt *S) { OS << S->getStmtClassName(); }
> +
> +  void Visit(QualType QT) {
> +OS << "QualType " << QT.split().Quals.getAsString();
> +  }
> +
> +  void Visit(const Type *T) { OS << T->getTypeClassName() << "Type"; }
> +
> +  void Visit(const comments::Comment *C, const comments::FullComment *FC)
> {
> +OS << C->getCommentKindName();
> +  }
> +
> +  void Visit(const CXXCtorInitializer *Init) { OS <<
> "CXXCtorInitializer"; }
> +
> +  void Visit(const Attr *A) {
> +switch (A->getKind()) {
> +#define ATTR(X)
>   \
> +  case attr::X:
>   \
> +OS << #X;
>   \
> +break;
> +#include "clang/Basic/AttrList.inc"
> +}
> +OS << "Attr";
> +  }
> +
> +  void Visit(const OMPClause *C) { OS << "OMPClause"; }
> +  void Visit(const TemplateArgument &A, SourceRange R = {},
> + const Decl *From = nullptr, const char *Label = nullptr) {
> +OS << "TemplateArgument";
> +  }
> +
> +  template  void Visit(T...) {}
> +};
> +
> +class TestASTDumper : public ASTNodeTraverser NodeTreePrinter> {
> +
> +  NodeTreePrinter MyNodeRecorder;
> +
> +public:
> +  TestASTDumper(llvm::raw_ostream &OS) : MyNodeRecorder(OS) {}
> +  NodeTreePrinter &doGetNodeDelegate() { return MyNodeRecorder; }
> +};
> +
> +template  std::string dumpASTString(NodeType &&...
> N) {
> +  std::string Buffer;
> +  llvm::raw_string_ostream OS(Buffer);
> +
> +  TestASTDumper Dumper(OS);
> +
> +  OS << "\n";
> +
> +  Dumper.Visit(std::forward(N)...);
> +
> +  return OS.str();
> +}
> +
> +const FunctionDecl *getFunctionNode(clang::ASTUnit *AST,
> +  

Re: r361033 - Add a Visit overload for DynTypedNode to ASTNodeTraverser

2019-05-17 Thread Yitzhak Mandelbaum via cfe-commits
i'll see if i can repro on my build and fix if so.

On Fri, May 17, 2019 at 1:56 PM Stephen Kelly  wrote:

> Hmm, thanks for letting me know!
>
> Is that an old compiler?
>
> I'm not near a computer for the weekend.
>
> Can someone fix or revert?
>
> Thanks,
>
> Stephen.
>
> On Fri 17 May 2019, 17:11 Yitzhak Mandelbaum,  wrote:
>
>> Looks like this caused a breakage:
>> http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/18641/steps/ninja%20check%201/logs/stdio
>>
>> On Fri, May 17, 2019 at 9:52 AM Stephen Kelly via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>>> Author: steveire
>>> Date: Fri May 17 06:55:28 2019
>>> New Revision: 361033
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=361033&view=rev
>>> Log:
>>> Add a Visit overload for DynTypedNode to ASTNodeTraverser
>>>
>>> Reviewers: aaron.ballman
>>>
>>> Subscribers: cfe-commits
>>>
>>> Tags: #clang
>>>
>>> Differential Revision: https://reviews.llvm.org/D61834
>>>
>>> Added:
>>> cfe/trunk/unittests/AST/ASTTraverserTest.cpp
>>> Modified:
>>> cfe/trunk/include/clang/AST/ASTNodeTraverser.h
>>> cfe/trunk/unittests/AST/CMakeLists.txt
>>>
>>> Modified: cfe/trunk/include/clang/AST/ASTNodeTraverser.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=361033&r1=361032&r2=361033&view=diff
>>>
>>> ==
>>> --- cfe/trunk/include/clang/AST/ASTNodeTraverser.h (original)
>>> +++ cfe/trunk/include/clang/AST/ASTNodeTraverser.h Fri May 17 06:55:28
>>> 2019
>>> @@ -205,6 +205,24 @@ public:
>>>  });
>>>}
>>>
>>> +  void Visit(const ast_type_traits::DynTypedNode &N) {
>>> +// FIXME: Improve this with a switch or a visitor pattern.
>>> +if (const auto *D = N.get())
>>> +  Visit(D);
>>> +else if (const auto *S = N.get())
>>> +  Visit(S);
>>> +else if (const auto *QT = N.get())
>>> +  Visit(*QT);
>>> +else if (const auto *T = N.get())
>>> +  Visit(T);
>>> +else if (const auto *C = N.get())
>>> +  Visit(C);
>>> +else if (const auto *C = N.get())
>>> +  Visit(C);
>>> +else if (const auto *T = N.get())
>>> +  Visit(*T);
>>> +  }
>>> +
>>>void dumpDeclContext(const DeclContext *DC) {
>>>  if (!DC)
>>>return;
>>>
>>> Added: cfe/trunk/unittests/AST/ASTTraverserTest.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTTraverserTest.cpp?rev=361033&view=auto
>>>
>>> ==
>>> --- cfe/trunk/unittests/AST/ASTTraverserTest.cpp (added)
>>> +++ cfe/trunk/unittests/AST/ASTTraverserTest.cpp Fri May 17 06:55:28 2019
>>> @@ -0,0 +1,220 @@
>>> +//===-
>>> unittests/AST/ASTTraverserTest.h===//
>>> +//
>>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
>>> Exceptions.
>>> +// See https://llvm.org/LICENSE.txt for license information.
>>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>>> +//
>>>
>>> +//===--===//
>>> +
>>> +#include "clang/AST/ASTContext.h"
>>> +#include "clang/AST/ASTNodeTraverser.h"
>>> +#include "clang/AST/TextNodeDumper.h"
>>> +#include "clang/ASTMatchers/ASTMatchFinder.h"
>>> +#include "clang/ASTMatchers/ASTMatchers.h"
>>> +#include "clang/Tooling/Tooling.h"
>>> +#include "gmock/gmock.h"
>>> +#include "gtest/gtest.h"
>>> +
>>> +using namespace clang::tooling;
>>> +using namespace clang::ast_matchers;
>>> +
>>> +namespace clang {
>>> +
>>> +class NodeTreePrinter : public TextTreeStructure {
>>> +  llvm::raw_ostream &OS;
>>> +
>>> +public:
>>> +  NodeTreePrinter(llvm::raw_ostream &OS)
>>> +  : TextTreeStructure(OS, /* showColors */ false), OS(OS) {}
>>> +
>>> +  void Visit(const Decl *D) { OS << D->getDeclKindName() << "Decl"; }
>>> +
>>> +  void Visit(const Stmt *S) { OS << S->getStmtClassName(); }
>>> +
>>> +  void Visit(QualType QT) {
>>> +OS << "QualType " << QT.split().Quals.getAsString();
>>> +  }
>>> +
>>> +  void Visit(const Type *T) { OS << T->getTypeClassName() << "Type"; }
>>> +
>>> +  void Visit(const comments::Comment *C, const comments::FullComment
>>> *FC) {
>>> +OS << C->getCommentKindName();
>>> +  }
>>> +
>>> +  void Visit(const CXXCtorInitializer *Init) { OS <<
>>> "CXXCtorInitializer"; }
>>> +
>>> +  void Visit(const Attr *A) {
>>> +switch (A->getKind()) {
>>> +#define ATTR(X)
>>> \
>>> +  case attr::X:
>>> \
>>> +OS << #X;
>>> \
>>> +break;
>>> +#include "clang/Basic/AttrList.inc"
>>> +}
>>> +OS << "Attr";
>>> +  }
>>> +
>>> +  void Visit(const OMPClause *C) { OS << "OMPClause"; }
>>> +  void Visit(const TemplateArgument &A, SourceRange R = {},
>>> + const Decl *From = nullptr, const char *Label = nullptr) {
>>> +OS << "TemplateArgument";
>>> +  }
>>> +
>>> +  template  void Visit(T...) {}
>>> +};
>>> 

r361152 - [LibTooling] Add RangeSelector library for defining source ranges based on bound AST nodes.

2019-05-20 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Mon May 20 06:15:14 2019
New Revision: 361152

URL: http://llvm.org/viewvc/llvm-project?rev=361152&view=rev
Log:
[LibTooling] Add RangeSelector library for defining source ranges based on 
bound AST nodes.

Summary:

The RangeSelector library defines a combinator language for specifying source
ranges based on bound ids for AST nodes.  The combinator approach follows the
design of the AST matchers.  The RangeSelectors defined here will be used in
both RewriteRule, for specifying source affected by edit, and in Stencil for
specifying source to use constructively in a replacement.

Reviewers: ilya-biryukov

Subscribers: mgorny, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D61774

Added:
cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
Modified:
cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
cfe/trunk/unittests/Tooling/CMakeLists.txt

Added: cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h?rev=361152&view=auto
==
--- cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h (added)
+++ cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h Mon May 20 
06:15:14 2019
@@ -0,0 +1,80 @@
+//===--- RangeSelector.h - Source-selection library -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+///  \file
+///  Defines a combinator library supporting the definition of _selectors_,
+///  which select source ranges based on (bound) AST nodes.
+///
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_
+#define LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include 
+
+namespace clang {
+namespace tooling {
+using RangeSelector = std::function(
+const ast_matchers::MatchFinder::MatchResult &)>;
+
+inline RangeSelector charRange(CharSourceRange R) {
+  return [R](const ast_matchers::MatchFinder::MatchResult &)
+ -> Expected { return R; };
+}
+
+/// Selects from the start of \p Begin and to the end of \p End.
+RangeSelector range(RangeSelector Begin, RangeSelector End);
+
+/// Convenience version of \c range where end-points are bound nodes.
+RangeSelector range(StringRef BeginID, StringRef EndID);
+
+/// Selects a node, including trailing semicolon (for non-expression
+/// statements). \p ID is the node's binding in the match result.
+RangeSelector node(StringRef ID);
+
+/// Selects a node, including trailing semicolon (always). Useful for selecting
+/// expression statements. \p ID is the node's binding in the match result.
+RangeSelector statement(StringRef ID);
+
+/// Given a \c MemberExpr, selects the member token. \p ID is the node's
+/// binding in the match result.
+RangeSelector member(StringRef ID);
+
+/// Given a node with a "name", (like \c NamedDecl, \c DeclRefExpr or \c
+/// CxxCtorInitializer) selects the name's token.  Only selects the final
+/// identifier of a qualified name, but not any qualifiers or template
+/// arguments.  For example, for `::foo::bar::baz` and `::foo::bar::baz`,
+/// it selects only `baz`.
+///
+/// \param ID is the node's binding in the match result.
+RangeSelector name(StringRef ID);
+
+// Given a \c CallExpr (bound to \p ID), selects the arguments' source text 
(all
+// source between the call's parentheses).
+RangeSelector callArgs(StringRef ID);
+
+// Given a \c CompoundStmt (bound to \p ID), selects the source of the
+// statements (all source between the braces).
+RangeSelector statements(StringRef ID);
+
+// Given a \c InitListExpr (bound to \p ID), selects the range of the elements
+// (all source between the braces).
+RangeSelector initListElements(StringRef ID);
+
+/// Selects the range from which `S` was expanded (possibly along with other
+/// source), if `S` is an expansion, and `S` itself, otherwise.  Corresponds to
+/// `SourceManager::getExpansionRange`.
+RangeSelector expansion(RangeSelector S);
+} // namespace tooling
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_

Modified: cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt?rev=361152&r1=361151&r2=361152&view=diff
==
--- cfe

r361160 - [LibTooling] Fix build break in test after r361152.

2019-05-20 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Mon May 20 07:44:40 2019
New Revision: 361160

URL: http://llvm.org/viewvc/llvm-project?rev=361160&view=rev
Log:
[LibTooling] Fix build break in test after r361152.

r361152 broke gcc builds.

Modified:
cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp

Modified: cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp?rev=361160&r1=361159&r2=361160&view=diff
==
--- cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp Mon May 20 07:44:40 2019
@@ -8,6 +8,7 @@
 
 #include "clang/Tooling/Refactoring/RangeSelector.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Frontend/ASTUnit.h"
 #include "clang/Tooling/FixIt.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/Support/Error.h"
@@ -31,7 +32,7 @@ using ::llvm::StringError;
 struct TestMatch {
   // The AST unit from which `result` is built. We bundle it because it backs
   // the result. Users are not expected to access it.
-  std::unique_ptr ASTUnit;
+  std::unique_ptr ASTUnit;
   // The result to use in the test. References `ast_unit`.
   MatchResult Result;
 };


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r361152 - [LibTooling] Add RangeSelector library for defining source ranges based on bound AST nodes.

2019-05-20 Thread Yitzhak Mandelbaum via cfe-commits
Nice, thanks for r361208.  As for support -- no, I didn't try that. I was
following a pattern I saw elsewhere.  Do you suggest that I make that
change? If so, any particular way to test it?

thanks

On Mon, May 20, 2019 at 8:26 PM Nico Weber  wrote:

> +  LLVMSupport
> +  LLVMTestingSupport
>
> clang/unittests/Tooling/CMakeLists already has this at the top:
> set(LLVM_LINK_COMPONENTS
>   ${LLVM_TARGETS_TO_BUILD}
>   Support
>   )
>
> I think we link Support twice now. Did adding TestingSupport up there not
> work? I'd expect that your addition would break shared library builds, or
> something like that.
>
> (Also, I tried to fix a build error that old gcc versions had with this
> change in r361208.)
>
> *From: *Yitzhak Mandelbaum via cfe-commits 
> *Date: *Mon, May 20, 2019 at 9:12 AM
> *To: * 
>
> Author: ymandel
>> Date: Mon May 20 06:15:14 2019
>> New Revision: 361152
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=361152&view=rev
>> Log:
>> [LibTooling] Add RangeSelector library for defining source ranges based
>> on bound AST nodes.
>>
>> Summary:
>>
>> The RangeSelector library defines a combinator language for specifying
>> source
>> ranges based on bound ids for AST nodes.  The combinator approach follows
>> the
>> design of the AST matchers.  The RangeSelectors defined here will be used
>> in
>> both RewriteRule, for specifying source affected by edit, and in Stencil
>> for
>> specifying source to use constructively in a replacement.
>>
>> Reviewers: ilya-biryukov
>>
>> Subscribers: mgorny, cfe-commits
>>
>> Tags: #clang
>>
>> Differential Revision: https://reviews.llvm.org/D61774
>>
>> Added:
>> cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
>> cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
>> cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
>> Modified:
>> cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
>> cfe/trunk/unittests/Tooling/CMakeLists.txt
>>
>> Added: cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h?rev=361152&view=auto
>>
>> ==
>> --- cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h (added)
>> +++ cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h Mon May
>> 20 06:15:14 2019
>> @@ -0,0 +1,80 @@
>> +//===--- RangeSelector.h - Source-selection library -*- C++
>> -*-===//
>> +//
>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
>> Exceptions.
>> +// See https://llvm.org/LICENSE.txt for license information.
>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>> +//
>>
>> +//===--===//
>> +///
>> +///  \file
>> +///  Defines a combinator library supporting the definition of
>> _selectors_,
>> +///  which select source ranges based on (bound) AST nodes.
>> +///
>>
>> +//===--===//
>> +
>> +#ifndef LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_
>> +#define LLVM_CLANG_TOOLING_REFACTOR_RANGE_SELECTOR_H_
>> +
>> +#include "clang/ASTMatchers/ASTMatchFinder.h"
>> +#include "clang/Basic/SourceLocation.h"
>> +#include "llvm/ADT/StringRef.h"
>> +#include "llvm/Support/Error.h"
>> +#include 
>> +
>> +namespace clang {
>> +namespace tooling {
>> +using RangeSelector = std::function(
>> +const ast_matchers::MatchFinder::MatchResult &)>;
>> +
>> +inline RangeSelector charRange(CharSourceRange R) {
>> +  return [R](const ast_matchers::MatchFinder::MatchResult &)
>> + -> Expected { return R; };
>> +}
>> +
>> +/// Selects from the start of \p Begin and to the end of \p End.
>> +RangeSelector range(RangeSelector Begin, RangeSelector End);
>> +
>> +/// Convenience version of \c range where end-points are bound nodes.
>> +RangeSelector range(StringRef BeginID, StringRef EndID);
>> +
>> +/// Selects a node, including trailing semicolon (for non-expression
>> +/// statements). \p ID is the node's binding in the match result.
>> +RangeSelector node(StringRef ID);
>> +
>> +/// Selects a node, including trailing semicolon (always). Useful for
>> selecting
>> +///

Re: r361152 - [LibTooling] Add RangeSelector library for defining source ranges based on bound AST nodes.

2019-05-21 Thread Yitzhak Mandelbaum via cfe-commits
https://reviews.llvm.org/D62201

On Tue, May 21, 2019 at 10:15 AM Nico Weber  wrote:

> I'm suggesting you make the below change. For testing, I'd just try
> building locally.
>
> $ git diff
> diff --git a/clang/unittests/Tooling/CMakeLists.txt
> b/clang/unittests/Tooling/CMakeLists.txt
> index 8c383be2d74..af8a35d9251 100644
> --- a/clang/unittests/Tooling/CMakeLists.txt
> +++ b/clang/unittests/Tooling/CMakeLists.txt
> @@ -1,6 +1,7 @@
>  set(LLVM_LINK_COMPONENTS
>${LLVM_TARGETS_TO_BUILD}
>Support
> +  TestingSupport
>)
>
>  # By default MSVC has a 2^16 limit on the number of sections in an object
> file,
> @@ -70,8 +71,6 @@ target_link_libraries(ToolingTests
>clangToolingCore
>clangToolingInclusions
>clangToolingRefactor
> -  LLVMSupport
> -  LLVMTestingSupport
>)
>
> On Mon, May 20, 2019 at 9:49 PM Yitzhak Mandelbaum 
> wrote:
>
>> Nice, thanks for r361208.  As for support -- no, I didn't try that. I
>> was following a pattern I saw elsewhere.  Do you suggest that I make that
>> change? If so, any particular way to test it?
>>
>> thanks
>>
>> On Mon, May 20, 2019 at 8:26 PM Nico Weber  wrote:
>>
>>> +  LLVMSupport
>>> +  LLVMTestingSupport
>>>
>>> clang/unittests/Tooling/CMakeLists already has this at the top:
>>> set(LLVM_LINK_COMPONENTS
>>>   ${LLVM_TARGETS_TO_BUILD}
>>>   Support
>>>   )
>>>
>>> I think we link Support twice now. Did adding TestingSupport up there
>>> not work? I'd expect that your addition would break shared library builds,
>>> or something like that.
>>>
>>> (Also, I tried to fix a build error that old gcc versions had with this
>>> change in r361208.)
>>>
>>> *From: *Yitzhak Mandelbaum via cfe-commits 
>>> *Date: *Mon, May 20, 2019 at 9:12 AM
>>> *To: * 
>>>
>>> Author: ymandel
>>>> Date: Mon May 20 06:15:14 2019
>>>> New Revision: 361152
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=361152&view=rev
>>>> Log:
>>>> [LibTooling] Add RangeSelector library for defining source ranges based
>>>> on bound AST nodes.
>>>>
>>>> Summary:
>>>>
>>>> The RangeSelector library defines a combinator language for specifying
>>>> source
>>>> ranges based on bound ids for AST nodes.  The combinator approach
>>>> follows the
>>>> design of the AST matchers.  The RangeSelectors defined here will be
>>>> used in
>>>> both RewriteRule, for specifying source affected by edit, and in
>>>> Stencil for
>>>> specifying source to use constructively in a replacement.
>>>>
>>>> Reviewers: ilya-biryukov
>>>>
>>>> Subscribers: mgorny, cfe-commits
>>>>
>>>> Tags: #clang
>>>>
>>>> Differential Revision: https://reviews.llvm.org/D61774
>>>>
>>>> Added:
>>>> cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
>>>> cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
>>>> cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
>>>> Modified:
>>>> cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
>>>> cfe/trunk/unittests/Tooling/CMakeLists.txt
>>>>
>>>> Added: cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h?rev=361152&view=auto
>>>>
>>>> ==
>>>> --- cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h (added)
>>>> +++ cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h Mon May
>>>> 20 06:15:14 2019
>>>> @@ -0,0 +1,80 @@
>>>> +//===--- RangeSelector.h - Source-selection library -*- C++
>>>> -*-===//
>>>> +//
>>>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
>>>> Exceptions.
>>>> +// See https://llvm.org/LICENSE.txt for license information.
>>>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>>>> +//
>>>>
>>>> +//===--===//
>>>> +///
>>>> +///  \file
>>>> +///  Defines a combinator library supporting the definitio

r361285 - [LibTooling] Address post-commit feedback for r361152

2019-05-21 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Tue May 21 11:48:58 2019
New Revision: 361285

URL: http://llvm.org/viewvc/llvm-project?rev=361285&view=rev
Log:
[LibTooling] Address post-commit feedback for r361152

Fixes a redundant dependency and moves another to its proper place.

Reviewers: thakis

Subscribers: mgorny, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62201

Modified:
cfe/trunk/unittests/Tooling/CMakeLists.txt

Modified: cfe/trunk/unittests/Tooling/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/CMakeLists.txt?rev=361285&r1=361284&r2=361285&view=diff
==
--- cfe/trunk/unittests/Tooling/CMakeLists.txt (original)
+++ cfe/trunk/unittests/Tooling/CMakeLists.txt Tue May 21 11:48:58 2019
@@ -1,6 +1,7 @@
 set(LLVM_LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
   Support
+  TestingSupport
   )
 
 # By default MSVC has a 2^16 limit on the number of sections in an object file,
@@ -70,8 +71,6 @@ target_link_libraries(ToolingTests
   clangToolingCore
   clangToolingInclusions
   clangToolingRefactor
-  LLVMSupport
-  LLVMTestingSupport
   )
 
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r361392 - [LibTooling] Update Transformer to use RangeSelector instead of NodePart enum.

2019-05-22 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed May 22 07:48:19 2019
New Revision: 361392

URL: http://llvm.org/viewvc/llvm-project?rev=361392&view=rev
Log:
[LibTooling] Update Transformer to use RangeSelector instead of NodePart enum.

Transformer provides an enum to indicate the range of source text to be edited.
That support is now redundant with the new (and more general) RangeSelector
library, so we remove the custom enum support in favor of supporting any
RangeSelector.

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62149

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=361392&r1=361391&r2=361392&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Wed May 22 
07:48:19 2019
@@ -19,6 +19,7 @@
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
 #include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "clang/Tooling/Refactoring/RangeSelector.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Error.h"
@@ -30,19 +31,6 @@
 
 namespace clang {
 namespace tooling {
-/// Determines the part of the AST node to replace.  We support this to work
-/// around the fact that the AST does not differentiate various syntactic
-/// elements into their own nodes, so users can specify them relative to a 
node,
-/// instead.
-enum class NodePart {
-  /// The node itself.
-  Node,
-  /// Given a \c MemberExpr, selects the member's token.
-  Member,
-  /// Given a \c NamedDecl or \c CxxCtorInitializer, selects that token of the
-  /// relevant name, not including qualifiers.
-  Name,
-};
 
 // Note that \p TextGenerator is allowed to fail, e.g. when trying to access a
 // matched node that was not bound.  Allowing this to fail simplifies error
@@ -76,73 +64,28 @@ inline TextGenerator text(std::string M)
 //   (`RewriteRule::Explanation`) instead.  Notes serve the rare cases wherein
 //   edit-specific diagnostics are required.
 //
-// `ASTEdit` should be built using the `change` convenience fucntions. For
+// `ASTEdit` should be built using the `change` convenience functions. For
 // example,
 // \code
-//   change(fun, NodePart::Name, "Frodo")
+//   change(name(fun), text("Frodo"))
 // \endcode
 // Or, if we use Stencil for the TextGenerator:
 // \code
-//   change(thenNode, stencil::cat("{", thenNode, "}"))
-//   change(call, NodePart::Args, stencil::cat(x, ",", y))
-// .note("argument order changed.")
+//   using stencil::cat;
+//   change(statement(thenNode), cat("{", thenNode, "}"))
+//   change(callArgs(call), cat(x, ",", y))
 // \endcode
 // Or, if you are changing the node corresponding to the rule's matcher, you 
can
 // use the single-argument override of \c change:
 // \code
-//   change("different_expr")
+//   change(cat("different_expr"))
 // \endcode
 struct ASTEdit {
-  // The (bound) id of the node whose source will be replaced.  This id should
-  // never be the empty string.
-  std::string Target;
-  ast_type_traits::ASTNodeKind Kind;
-  NodePart Part;
+  RangeSelector TargetRange;
   TextGenerator Replacement;
   TextGenerator Note;
 };
 
-// Convenience functions for creating \c ASTEdits.  They all must be explicitly
-// instantiated with the desired AST type.  Each overload includes both \c
-// std::string and \c TextGenerator versions.
-
-// FIXME: For overloads taking a \c NodePart, constrain the valid values of \c
-// Part based on the type \c T.
-template 
-ASTEdit change(StringRef Target, NodePart Part, TextGenerator Replacement) {
-  ASTEdit E;
-  E.Target = Target.str();
-  E.Kind = ast_type_traits::ASTNodeKind::getFromNodeKind();
-  E.Part = Part;
-  E.Replacement = std::move(Replacement);
-  return E;
-}
-
-template 
-ASTEdit change(StringRef Target, NodePart Part, std::string Replacement) {
-  return change(Target, Part, text(std::move(Replacement)));
-}
-
-/// Variant of \c change for which the NodePart defaults to the whole node.
-template 
-ASTEdit change(StringRef Target, TextGenerator Replacement) {
-  return change(Target, NodePart::Node, std::move(Replacement));
-}
-
-/// Variant of \c change for which the NodePart defaults to the whole node.
-template 
-ASTEdit change(StringRef Target, std::string Replacement) {
-  return change(Target, text(std::move(Replacement)));
-}
-
-/// Variant of \c change that selects the node of the entire match.
-template  ASTEdit change(TextGenerator Replacement);
-
-/// Variant of \c change that selects the node of the entire match.
-template  ASTEdi

r361413 - [LibTooling] Update Stencil to use RangeSelector

2019-05-22 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed May 22 11:03:00 2019
New Revision: 361413

URL: http://llvm.org/viewvc/llvm-project?rev=361413&view=rev
Log:
[LibTooling] Update Stencil to use RangeSelector

Add support for creating a `StencilPart` from any `RangeSelector`, which
broadens the scope of `Stencil`.

Correspondingly, deprecate Stencil's specialized combinators `node` and `sNode`
in favor of using the new `selection` combinator directly (with the appropriate
range selector).

Reviewers: sbenza

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62160

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
cfe/trunk/unittests/Tooling/StencilTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h?rev=361413&r1=361412&r2=361413&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h Wed May 22 11:03:00 
2019
@@ -23,6 +23,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTTypeTraits.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Refactoring/RangeSelector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
 #include 
@@ -121,6 +122,7 @@ public:
 private:
   friend bool operator==(const Stencil &A, const Stencil &B);
   static StencilPart wrap(llvm::StringRef Text);
+  static StencilPart wrap(RangeSelector Selector);
   static StencilPart wrap(StencilPart Part) { return Part; }
 
   std::vector Parts;
@@ -142,14 +144,24 @@ template  Stencil cat(Ts
 /// \returns exactly the text provided.
 StencilPart text(llvm::StringRef Text);
 
+/// \returns the source corresponding to the selected range.
+StencilPart selection(RangeSelector Selector);
+
 /// \returns the source corresponding to the identified node.
-StencilPart node(llvm::StringRef Id);
+/// FIXME: Deprecated. Write `selection(node(Id))` instead.
+inline StencilPart node(llvm::StringRef Id) {
+  return selection(tooling::node(Id));
+}
+
 /// Variant of \c node() that identifies the node as a statement, for purposes
 /// of deciding whether to include any trailing semicolon.  Only relevant for
 /// Expr nodes, which, by default, are *not* considered as statements.
 /// \returns the source corresponding to the identified node, considered as a
 /// statement.
-StencilPart sNode(llvm::StringRef Id);
+/// FIXME: Deprecated. Write `selection(statement(Id))` instead.
+inline StencilPart sNode(llvm::StringRef Id) {
+  return selection(tooling::statement(Id));
+}
 
 /// For debug use only; semantics are not guaranteed.
 ///

Modified: cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp?rev=361413&r1=361412&r2=361413&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp Wed May 22 11:03:00 2019
@@ -55,22 +55,11 @@ struct DebugPrintNodeOpData {
   explicit DebugPrintNodeOpData(std::string S) : Id(std::move(S)) {}
   std::string Id;
 };
-// Whether to associate a trailing semicolon with a node when identifying it's
-// text.  This flag is needed for expressions (clang::Expr), because their role
-// is ambiguous when they are also complete statements.  When this flag is
-// `Always`, an expression node will be treated like a statement, and will
-// therefore be associated with any trailing semicolon.
-enum class SemiAssociation : bool {
-  Always,
-  Inferred,
-};
 
-// A reference to a particular (bound) AST node.
-struct NodeRefData {
-  explicit NodeRefData(std::string S, SemiAssociation SA)
-  : Id(std::move(S)), SemiAssoc(SA) {}
-  std::string Id;
-  SemiAssociation SemiAssoc;
+// The fragment of code corresponding to the selected range.
+struct SelectorOpData {
+  explicit SelectorOpData(RangeSelector S) : Selector(std::move(S)) {}
+  RangeSelector Selector;
 };
 } // namespace
 
@@ -82,9 +71,8 @@ bool isEqualData(const DebugPrintNodeOpD
   return A.Id == B.Id;
 }
 
-bool isEqualData(const NodeRefData &A, const NodeRefData &B) {
-  return A.Id == B.Id && A.SemiAssoc == B.SemiAssoc;
-}
+// Equality is not (yet) defined for \c RangeSelector.
+bool isEqualData(const SelectorOpData &, const SelectorOpData &) { return 
false; }
 
 // The `evalData()` overloads evaluate the given stencil data to a string, 
given
 // the match result, and append it to `Result`. We define an overload for each
@@ -108,25 +96,12 @@ Error evalData(const DebugPrintNodeOpDat
   return Error::success();
 }
 
-Error evalData(const NodeRefData &Data, const MatchFinder::MatchResult &Match,
+Error evalData(const SelectorOpData &Data, const MatchFinder::Ma

[clang-tools-extra] r361418 - [clang-tidy] Add support for writing a check as a Transformer rewrite rule.

2019-05-22 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed May 22 11:56:18 2019
New Revision: 361418

URL: http://llvm.org/viewvc/llvm-project?rev=361418&view=rev
Log:
[clang-tidy] Add support for writing a check as a Transformer rewrite rule.

This revision introduces an adaptor from Transformer's rewrite rules
(`clang::tooling::RewriteRule`) to `ClangTidyCheck`.  For example, given a
RewriteRule `MyCheckAsRewriteRule`, it lets one define a tidy check as follows:

```
class MyTidyCheck : public TransformerClangTidyCheck {
 public:
  MyTidyCheck(StringRef Name, ClangTidyContext *Context)
  : TransformerClangTidyCheck(MyCheckAsRewriteRule, Name, Context) {}
};
```

Reviewers: aaron.ballman

Subscribers: mgorny, xazax.hun, cfe-commits, ilya-biryukov

Tags: #clang

Differential Revision: https://reviews.llvm.org/D61386

Added:
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h

clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt?rev=361418&r1=361417&r2=361418&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt Wed May 22 11:56:18 
2019
@@ -13,6 +13,7 @@ add_clang_library(clangTidyUtils
   LexerUtils.cpp
   NamespaceAliaser.cpp
   OptionsUtils.cpp
+  TransformerClangTidyCheck.cpp
   TypeTraits.cpp
   UsingInserter.cpp
 
@@ -22,4 +23,5 @@ add_clang_library(clangTidyUtils
   clangBasic
   clangLex
   clangTidy
+  clangToolingRefactor
   )

Added: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp?rev=361418&view=auto
==
--- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp 
(added)
+++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp Wed 
May 22 11:56:18 2019
@@ -0,0 +1,63 @@
+//===-- TransformerClangTidyCheck.cpp - clang-tidy 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "TransformerClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace utils {
+using tooling::RewriteRule;
+
+void TransformerClangTidyCheck::registerMatchers(
+ast_matchers::MatchFinder *Finder) {
+  Finder->addDynamicMatcher(tooling::detail::buildMatcher(Rule), this);
+}
+
+void TransformerClangTidyCheck::check(
+const ast_matchers::MatchFinder::MatchResult &Result) {
+  if (Result.Context->getDiagnostics().hasErrorOccurred())
+return;
+
+  // Verify the existence and validity of the AST node that roots this rule.
+  const ast_matchers::BoundNodes::IDToNodeMap &NodesMap = 
Result.Nodes.getMap();
+  auto Root = NodesMap.find(RewriteRule::RootID);
+  assert(Root != NodesMap.end() && "Transformation failed: missing root 
node.");
+  SourceLocation RootLoc = Result.SourceManager->getExpansionLoc(
+  Root->second.getSourceRange().getBegin());
+  assert(RootLoc.isValid() && "Invalid location for Root node of match.");
+
+  RewriteRule::Case Case = tooling::detail::findSelectedCase(Result, Rule);
+  Expected> Transformations =
+  tooling::detail::translateEdits(Result, Case.Edits);
+  if (!Transformations) {
+llvm::errs() << "Rewrite failed: "
+ << llvm::toString(Transformations.takeError()) << "\n";
+return;
+  }
+
+  // No rewrite applied, but no error encountered either.
+  if (Transformations->empty())
+return;
+
+  StringRef Message = "no explanation";
+  if (Case.Explanation) {
+if (Expected E = Case.Explanation(Result))
+  Message = *E;
+else
+  llvm::errs() << "Error in explanation: " << llvm::toString(E.takeError())
+   << "\n";
+  }
+  DiagnosticBuilder Diag = diag(RootLoc, Message);
+  for (const auto &T : *Transformations) {
+Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
+  }
+}
+
+} // namespace utils
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h?rev=361418&view=auto
==
--- clang-tool

Re: [PATCH] D61774: [LibTooling] Add RangeSelector library for defining source ranges based on bound AST nodes.

2019-05-22 Thread Yitzhak Mandelbaum via cfe-commits
I'm confused by the error given that getStatementsRange is a function
name.  I don't have Visual Studio -- can you find a fix and send a patch? I
wonder if taking the address explicitly is enough?  Or, if you know how to
trigger this error in clang or gcc, I can fix it myself.

On Wed, May 22, 2019 at 4:31 PM Petr Penzin via Phabricator <
revi...@reviews.llvm.org> wrote:

> penzn added inline comments.
>
>
> 
> Comment at: cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp:229
> +RangeSelector tooling::statements(StringRef ID) {
> +  return RelativeSelector(ID);
> +}
> 
> Sorry for posting here, haven't gotten my bugzilla access yet (requested
> though).
>
> This breaks with Visual Studio 2017 (15.7.6):
>
> RangeSelector.cpp(229): error C2971:
> '`anonymous-namespace'::RelativeSelector': template parameter 'Func':
> 'getStatementsRange': a variable with non-static storage duration cannot be
> used as a non-type argument
>
>
> Repository:
>   rL LLVM
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D61774/new/
>
> https://reviews.llvm.org/D61774
>
>
>
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D62201: [LibTooling] Address post-commit feedback for r361152

2019-05-23 Thread Yitzhak Mandelbaum via cfe-commits
Fixed in https://reviews.llvm.org/D62320

On Thu, May 23, 2019 at 10:44 AM Sam Clegg via Phabricator <
revi...@reviews.llvm.org> wrote:

> sbc100 added a comment.
>
> I think this build broke the `-DLLVM_BUILD_LLVM_DYLIB=ON
> -DLLVM_LINK_LLVM_DYLIB=ON` build. e.g
> https://ci.chromium.org/p/wasm/builders/ci/linux/6457
>
>   FAILED: tools/clang/unittests/Tooling/ToolingTests
>   : &&
> /b/swarming/w/ir/cache/builder/src/src/work/v8/v8/third_party/llvm-build/Release+Asserts/bin/clang++
>  -fPIC -fvisibility-inlines-hidden -Werror=date-time
> -Werror=unguarded-availability-new -std=c++11 -Wall -Wextra
> -Wno-unused-parameter -Wwrite-strings -Wcast-qual
> -Wmissing-field-initializers -pedantic -Wno-long-long
> -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type
> -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion
> -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common
> -Woverloaded-virtual -Wno-nested-anon-types -O3
> -Wl,-allow-shlib-undefined-Wl,-O3 -Wl,--gc-sections
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/ASTSelectionTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/CastExprTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/CommentHandlerTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/CompilationDatabaseTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/DiagnosticsYamlTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/ExecutionTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/FixItTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/HeaderIncludesTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/LexicallyOrderedRecursiveASTVisitorTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/LookupTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/QualTypeNamesTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RangeSelectorTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/Attr.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/Class.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/ConstructExpr.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/CXXMemberCall.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/DeclRefExpr.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/ImplicitCtor.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/InitListExprPostOrder.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/InitListExprPreOrder.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/IntegerLiteral.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/LambdaExpr.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/ParenExpr.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTests/TraversalScope.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTestDeclVisitor.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTestPostOrderVisitor.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RecursiveASTVisitorTestTypeLocVisitor.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RefactoringActionRulesTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RefactoringCallbacksTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RefactoringTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/ReplacementsYamlTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/RewriterTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/SourceCodeTest.cpp.o
> tools/clang/unittests/Tooling/CMakeFiles/ToolingTests.dir/StencilTe

Re: [PATCH] D61774: [LibTooling] Add RangeSelector library for defining source ranges based on bound AST nodes.

2019-05-23 Thread Yitzhak Mandelbaum via cfe-commits
Sounds good. I'll send a fix shortly. Found another bug too (captured a
StringRef in a lambda) -- shall i bundle the fixes?

On Thu, May 23, 2019 at 9:01 AM Ilya Biryukov  wrote:

> Maybe go with a runtime parameter (of type llvm::function_ref) instead of
> the template parameter?
> In any non-trivial example, the runtime costs of another function pointer
> should be negligible given that we need to parse the ASTs, run the
> matchers, etc.
>
> On Wed, May 22, 2019 at 10:48 PM Penzin, Petr 
> wrote:
>
>> It does not like some part of that instantiation, I am not sure which one
>> yet. Let’s see what I can do about it.
>>
>>
>>
>> -Petr
>>
>>
>>
>> *From:* Yitzhak Mandelbaum [mailto:yitzh...@google.com]
>> *Sent:* Wednesday, May 22, 2019 1:37 PM
>> *To:* reviews+d61774+public+f458bb6144ae8...@reviews.llvm.org
>> *Cc:* Ilya Biryukov ; Penzin, Petr <
>> petr.pen...@intel.com>; llvm-comm...@lists.llvm.org; Michał Górny <
>> mgo...@gentoo.org>; cfe-commits ; Theko
>> Lekena ; Nicolas Lesser ;
>> Han Shen 
>> *Subject:* Re: [PATCH] D61774: [LibTooling] Add RangeSelector library
>> for defining source ranges based on bound AST nodes.
>>
>>
>>
>> I'm confused by the error given that getStatementsRange is a function
>> name.  I don't have Visual Studio -- can you find a fix and send a patch? I
>> wonder if taking the address explicitly is enough?  Or, if you know how to
>> trigger this error in clang or gcc, I can fix it myself.
>>
>>
>>
>> On Wed, May 22, 2019 at 4:31 PM Petr Penzin via Phabricator <
>> revi...@reviews.llvm.org> wrote:
>>
>> penzn added inline comments.
>>
>>
>> 
>> Comment at: cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp:229
>> +RangeSelector tooling::statements(StringRef ID) {
>> +  return RelativeSelector(ID);
>> +}
>> 
>> Sorry for posting here, haven't gotten my bugzilla access yet (requested
>> though).
>>
>> This breaks with Visual Studio 2017 (15.7.6):
>>
>> RangeSelector.cpp(229): error C2971:
>> '`anonymous-namespace'::RelativeSelector': template parameter 'Func':
>> 'getStatementsRange': a variable with non-static storage duration cannot be
>> used as a non-type argument
>>
>>
>> Repository:
>>   rL LLVM
>>
>> CHANGES SINCE LAST ACTION
>>   https://reviews.llvm.org/D61774/new/
>>
>> https://reviews.llvm.org/D61774
>>
>>
>>
>
> --
> Regards,
> Ilya Biryukov
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D61774: [LibTooling] Add RangeSelector library for defining source ranges based on bound AST nodes.

2019-05-23 Thread Yitzhak Mandelbaum via cfe-commits
Given that we'll need to store the function reference, is
llvm::function_ref still the way to go? The comments seem to warn away from
storing function_refs.

On Thu, May 23, 2019 at 11:06 AM Yitzhak Mandelbaum 
wrote:

> Sounds good. I'll send a fix shortly. Found another bug too (captured a
> StringRef in a lambda) -- shall i bundle the fixes?
>
> On Thu, May 23, 2019 at 9:01 AM Ilya Biryukov 
> wrote:
>
>> Maybe go with a runtime parameter (of type llvm::function_ref) instead of
>> the template parameter?
>> In any non-trivial example, the runtime costs of another function pointer
>> should be negligible given that we need to parse the ASTs, run the
>> matchers, etc.
>>
>> On Wed, May 22, 2019 at 10:48 PM Penzin, Petr 
>> wrote:
>>
>>> It does not like some part of that instantiation, I am not sure which
>>> one yet. Let’s see what I can do about it.
>>>
>>>
>>>
>>> -Petr
>>>
>>>
>>>
>>> *From:* Yitzhak Mandelbaum [mailto:yitzh...@google.com]
>>> *Sent:* Wednesday, May 22, 2019 1:37 PM
>>> *To:* reviews+d61774+public+f458bb6144ae8...@reviews.llvm.org
>>> *Cc:* Ilya Biryukov ; Penzin, Petr <
>>> petr.pen...@intel.com>; llvm-comm...@lists.llvm.org; Michał Górny <
>>> mgo...@gentoo.org>; cfe-commits ; Theko
>>> Lekena ; Nicolas Lesser ;
>>> Han Shen 
>>> *Subject:* Re: [PATCH] D61774: [LibTooling] Add RangeSelector library
>>> for defining source ranges based on bound AST nodes.
>>>
>>>
>>>
>>> I'm confused by the error given that getStatementsRange is a function
>>> name.  I don't have Visual Studio -- can you find a fix and send a patch? I
>>> wonder if taking the address explicitly is enough?  Or, if you know how to
>>> trigger this error in clang or gcc, I can fix it myself.
>>>
>>>
>>>
>>> On Wed, May 22, 2019 at 4:31 PM Petr Penzin via Phabricator <
>>> revi...@reviews.llvm.org> wrote:
>>>
>>> penzn added inline comments.
>>>
>>>
>>> 
>>> Comment at: cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp:229
>>> +RangeSelector tooling::statements(StringRef ID) {
>>> +  return RelativeSelector(ID);
>>> +}
>>> 
>>> Sorry for posting here, haven't gotten my bugzilla access yet (requested
>>> though).
>>>
>>> This breaks with Visual Studio 2017 (15.7.6):
>>>
>>> RangeSelector.cpp(229): error C2971:
>>> '`anonymous-namespace'::RelativeSelector': template parameter 'Func':
>>> 'getStatementsRange': a variable with non-static storage duration cannot be
>>> used as a non-type argument
>>>
>>>
>>> Repository:
>>>   rL LLVM
>>>
>>> CHANGES SINCE LAST ACTION
>>>   https://reviews.llvm.org/D61774/new/
>>>
>>> https://reviews.llvm.org/D61774
>>>
>>>
>>>
>>
>> --
>> Regards,
>> Ilya Biryukov
>>
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D61774: [LibTooling] Add RangeSelector library for defining source ranges based on bound AST nodes.

2019-05-23 Thread Yitzhak Mandelbaum via cfe-commits
Actually, someone already committed a fix: https://reviews.llvm.org/D62202

I can still make this change if it seems worthwhile, but its not strictly
necessary at this point.

On Thu, May 23, 2019 at 11:14 AM Yitzhak Mandelbaum 
wrote:

> Given that we'll need to store the function reference, is
> llvm::function_ref still the way to go? The comments seem to warn away from
> storing function_refs.
>
> On Thu, May 23, 2019 at 11:06 AM Yitzhak Mandelbaum 
> wrote:
>
>> Sounds good. I'll send a fix shortly. Found another bug too (captured a
>> StringRef in a lambda) -- shall i bundle the fixes?
>>
>> On Thu, May 23, 2019 at 9:01 AM Ilya Biryukov 
>> wrote:
>>
>>> Maybe go with a runtime parameter (of type llvm::function_ref) instead
>>> of the template parameter?
>>> In any non-trivial example, the runtime costs of another function
>>> pointer should be negligible given that we need to parse the ASTs, run the
>>> matchers, etc.
>>>
>>> On Wed, May 22, 2019 at 10:48 PM Penzin, Petr 
>>> wrote:
>>>
 It does not like some part of that instantiation, I am not sure which
 one yet. Let’s see what I can do about it.



 -Petr



 *From:* Yitzhak Mandelbaum [mailto:yitzh...@google.com]
 *Sent:* Wednesday, May 22, 2019 1:37 PM
 *To:* reviews+d61774+public+f458bb6144ae8...@reviews.llvm.org
 *Cc:* Ilya Biryukov ; Penzin, Petr <
 petr.pen...@intel.com>; llvm-comm...@lists.llvm.org; Michał Górny <
 mgo...@gentoo.org>; cfe-commits ; Theko
 Lekena ; Nicolas Lesser ;
 Han Shen 
 *Subject:* Re: [PATCH] D61774: [LibTooling] Add RangeSelector library
 for defining source ranges based on bound AST nodes.



 I'm confused by the error given that getStatementsRange is a function
 name.  I don't have Visual Studio -- can you find a fix and send a patch? I
 wonder if taking the address explicitly is enough?  Or, if you know how to
 trigger this error in clang or gcc, I can fix it myself.



 On Wed, May 22, 2019 at 4:31 PM Petr Penzin via Phabricator <
 revi...@reviews.llvm.org> wrote:

 penzn added inline comments.


 
 Comment at: cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp:229
 +RangeSelector tooling::statements(StringRef ID) {
 +  return RelativeSelector(ID);
 +}
 
 Sorry for posting here, haven't gotten my bugzilla access yet
 (requested though).

 This breaks with Visual Studio 2017 (15.7.6):

 RangeSelector.cpp(229): error C2971:
 '`anonymous-namespace'::RelativeSelector': template parameter 'Func':
 'getStatementsRange': a variable with non-static storage duration cannot be
 used as a non-type argument


 Repository:
   rL LLVM

 CHANGES SINCE LAST ACTION
   https://reviews.llvm.org/D61774/new/

 https://reviews.llvm.org/D61774



>>>
>>> --
>>> Regards,
>>> Ilya Biryukov
>>>
>>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r361514 - [LibTooling] Fix dangling references in RangeSelector.

2019-05-23 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu May 23 10:11:33 2019
New Revision: 361514

URL: http://llvm.org/viewvc/llvm-project?rev=361514&view=rev
Log:
[LibTooling] Fix dangling references in RangeSelector.

Summary:
RangeSelector had a number of cases of capturing a StringRef in a lambda, which
lead to dangling references. This change converts all uses in the API of
`StringRef` to `std::string` to avoid this problem. `std::string` in the API is
a reasonable choice, because the combinators are always storing the string
beyond the life of the combinator construction.

Reviewers: ilya-biryukov, gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62328

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h?rev=361514&r1=361513&r2=361514&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h Thu May 23 
10:11:33 2019
@@ -17,9 +17,9 @@
 
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
 #include 
+#include 
 
 namespace clang {
 namespace tooling {
@@ -35,19 +35,19 @@ inline RangeSelector charRange(CharSourc
 RangeSelector range(RangeSelector Begin, RangeSelector End);
 
 /// Convenience version of \c range where end-points are bound nodes.
-RangeSelector range(StringRef BeginID, StringRef EndID);
+RangeSelector range(std::string BeginID, std::string EndID);
 
 /// Selects a node, including trailing semicolon (for non-expression
 /// statements). \p ID is the node's binding in the match result.
-RangeSelector node(StringRef ID);
+RangeSelector node(std::string ID);
 
 /// Selects a node, including trailing semicolon (always). Useful for selecting
 /// expression statements. \p ID is the node's binding in the match result.
-RangeSelector statement(StringRef ID);
+RangeSelector statement(std::string ID);
 
 /// Given a \c MemberExpr, selects the member token. \p ID is the node's
 /// binding in the match result.
-RangeSelector member(StringRef ID);
+RangeSelector member(std::string ID);
 
 /// Given a node with a "name", (like \c NamedDecl, \c DeclRefExpr or \c
 /// CxxCtorInitializer) selects the name's token.  Only selects the final
@@ -56,19 +56,19 @@ RangeSelector member(StringRef ID);
 /// it selects only `baz`.
 ///
 /// \param ID is the node's binding in the match result.
-RangeSelector name(StringRef ID);
+RangeSelector name(std::string ID);
 
 // Given a \c CallExpr (bound to \p ID), selects the arguments' source text 
(all
 // source between the call's parentheses).
-RangeSelector callArgs(StringRef ID);
+RangeSelector callArgs(std::string ID);
 
 // Given a \c CompoundStmt (bound to \p ID), selects the source of the
 // statements (all source between the braces).
-RangeSelector statements(StringRef ID);
+RangeSelector statements(std::string ID);
 
 // Given a \c InitListExpr (bound to \p ID), selects the range of the elements
 // (all source between the braces).
-RangeSelector initListElements(StringRef ID);
+RangeSelector initListElements(std::string ID);
 
 /// Selects the range from which `S` was expanded (possibly along with other
 /// source), if `S` is an expansion, and `S` itself, otherwise.  Corresponds to

Modified: cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp?rev=361514&r1=361513&r2=361514&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp Thu May 23 10:11:33 2019
@@ -104,7 +104,7 @@ static SourceLocation findOpenParen(cons
   return findPreviousTokenKind(EndLoc, SM, LangOpts, tok::TokenKind::l_paren);
 }
 
-RangeSelector tooling::node(StringRef ID) {
+RangeSelector tooling::node(std::string ID) {
   return [ID](const MatchResult &Result) -> Expected {
 Expected Node = getNode(Result.Nodes, ID);
 if (!Node)
@@ -115,7 +115,7 @@ RangeSelector tooling::node(StringRef ID
   };
 }
 
-RangeSelector tooling::statement(StringRef ID) {
+RangeSelector tooling::statement(std::string ID) {
   return [ID](const MatchResult &Result) -> Expected {
 Expected Node = getNode(Result.Nodes, ID);
 if (!Node)
@@ -143,11 +143,11 @@ RangeSelector tooling::range(RangeSelect
   };
 }
 
-RangeSelector tooling::range(StringRef BeginID, StringRef EndID) {
-  return tooling::range(node(BeginID), node(EndID));
+RangeSelector tooling::range(std::string BeginID, std::string EndID) {
+  return tooling::ran

r361643 - [LibTooling] Add Explanation parameter to `makeRule`.

2019-05-24 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri May 24 08:11:45 2019
New Revision: 361643

URL: http://llvm.org/viewvc/llvm-project?rev=361643&view=rev
Log:
[LibTooling] Add Explanation parameter to `makeRule`.

Summary:
Conceptually, a single-case RewriteRule has a matcher, edit(s) and an (optional)
explanation. `makeRule` previously only took the matcher and edit(s). This
change adds (optional) support for the explanation.

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62390

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=361643&r1=361642&r2=361643&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Fri May 24 
08:11:45 2019
@@ -125,14 +125,16 @@ struct RewriteRule {
 
 /// Convenience function for constructing a simple \c RewriteRule.
 RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
- SmallVector Edits);
+ SmallVector Edits,
+ TextGenerator Explanation = nullptr);
 
 /// Convenience overload of \c makeRule for common case of only one edit.
 inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
-ASTEdit Edit) {
+ASTEdit Edit,
+TextGenerator Explanation = nullptr) {
   SmallVector Edits;
   Edits.emplace_back(std::move(Edit));
-  return makeRule(std::move(M), std::move(Edits));
+  return makeRule(std::move(M), std::move(Edits), std::move(Explanation));
 }
 
 /// Applies the first rule whose pattern matches; other rules are ignored.

Modified: cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp?rev=361643&r1=361642&r2=361643&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp Fri May 24 08:11:45 2019
@@ -96,10 +96,10 @@ ASTEdit tooling::change(RangeSelector S,
   return E;
 }
 
-RewriteRule tooling::makeRule(DynTypedMatcher M,
-  SmallVector Edits) {
-  return RewriteRule{
-  {RewriteRule::Case{std::move(M), std::move(Edits), nullptr}}};
+RewriteRule tooling::makeRule(DynTypedMatcher M, SmallVector Edits,
+  TextGenerator Explanation) {
+  return RewriteRule{{RewriteRule::Case{std::move(M), std::move(Edits),
+std::move(Explanation)}}};
 }
 
 // Determines whether A is a base type of B in the class hierarchy, including

Modified: cfe/trunk/unittests/Tooling/TransformerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/TransformerTest.cpp?rev=361643&r1=361642&r2=361643&view=diff
==
--- cfe/trunk/unittests/Tooling/TransformerTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/TransformerTest.cpp Fri May 24 08:11:45 2019
@@ -147,8 +147,7 @@ static RewriteRule ruleStrlenSize() {
   on(expr(hasType(isOrPointsTo(StringType)))
  .bind(StringExpr)),
   callee(cxxMethodDecl(hasName("c_str")),
-  change(text("REPLACED")));
-  R.Cases[0].Explanation = text("Use size() method directly on string.");
+  change(text("REPLACED")), text("Use size() method directly on string."));
   return R;
 }
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r361647 - [clang-tidy] In TransformerClangTidyCheck, require Explanation field.

2019-05-24 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri May 24 09:32:03 2019
New Revision: 361647

URL: http://llvm.org/viewvc/llvm-project?rev=361647&view=rev
Log:
[clang-tidy] In TransformerClangTidyCheck, require Explanation field.

Summary:
In general, the `Explanation` field is optional in `RewriteRule` cases. But,
because the primary purpose of clang-tidy checks is to provide users with
diagnostics, we assume that a missing explanation is a bug.  This change adds an
assertion that checks all cases for an explanation, and updates the code to rely
on that assertion correspondingly.

Reviewers: ilya-biryukov

Subscribers: xazax.hun, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62340

Modified:
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h

clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp?rev=361647&r1=361646&r2=361647&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp Fri 
May 24 09:32:03 2019
@@ -13,6 +13,17 @@ namespace tidy {
 namespace utils {
 using tooling::RewriteRule;
 
+TransformerClangTidyCheck::TransformerClangTidyCheck(tooling::RewriteRule R,
+ StringRef Name,
+ ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context), Rule(std::move(R)) {
+  for (const auto &Case : Rule.Cases) {
+assert(Case.Explanation != nullptr &&
+   "clang-tidy checks must have an explanation by default;"
+   " explicitly provide an empty explanation if none is desired");
+  }
+}
+
 void TransformerClangTidyCheck::registerMatchers(
 ast_matchers::MatchFinder *Finder) {
   Finder->addDynamicMatcher(tooling::detail::buildMatcher(Rule), this);
@@ -44,15 +55,13 @@ void TransformerClangTidyCheck::check(
   if (Transformations->empty())
 return;
 
-  StringRef Message = "no explanation";
-  if (Case.Explanation) {
-if (Expected E = Case.Explanation(Result))
-  Message = *E;
-else
-  llvm::errs() << "Error in explanation: " << llvm::toString(E.takeError())
-   << "\n";
+  Expected Explanation = Case.Explanation(Result);
+  if (!Explanation) {
+llvm::errs() << "Error in explanation: "
+ << llvm::toString(Explanation.takeError()) << "\n";
+return;
   }
-  DiagnosticBuilder Diag = diag(RootLoc, Message);
+  DiagnosticBuilder Diag = diag(RootLoc, *Explanation);
   for (const auto &T : *Transformations) {
 Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
   }

Modified: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h?rev=361647&r1=361646&r2=361647&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h 
(original)
+++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h Fri 
May 24 09:32:03 2019
@@ -31,10 +31,14 @@ namespace utils {
 // };
 class TransformerClangTidyCheck : public ClangTidyCheck {
 public:
+  // All cases in \p R must have a non-null \c Explanation, even though \c
+  // Explanation is optional for RewriteRule in general. Because the primary
+  // purpose of clang-tidy checks is to provide users with diagnostics, we
+  // assume that a missing explanation is a bug.  If no explanation is desired,
+  // indicate that explicitly (for example, by passing `text("no explanation")`
+  //  to `makeRule` as the `Explanation` argument).
   TransformerClangTidyCheck(tooling::RewriteRule R, StringRef Name,
-ClangTidyContext *Context)
-  : ClangTidyCheck(Name, Context), Rule(std::move(R)) {}
-
+ClangTidyContext *Context);
   void registerMatchers(ast_matchers::MatchFinder *Finder) final;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
 

Modified: 
clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp?rev=361647&r1=361646&r2=361647&view=diff
==
--- 
clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp 
(original)
+++ 
clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp 
Fri May 24 09:32:03 2019

Re: [PATCH] D62340: [clang-tidy] In TransformerClangTidyCheck, require Explanation field.

2019-05-24 Thread Yitzhak Mandelbaum via cfe-commits
looking now...

On Fri, May 24, 2019 at 12:49 PM Ilya Biryukov  wrote:

> This seems to produce warnings about unused variables:
> …/llvm/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp:20:20:
> warning: unused variable 'Case' [-Wunused-variable]
>
>   for (const auto &Case : Rule.Cases) {
>
> Could you take a look?
>
> On Fri, May 24, 2019 at 6:29 PM Yitzhak Mandelbaum via Phabricator <
> revi...@reviews.llvm.org> wrote:
>
>> This revision was automatically updated to reflect the committed changes.
>> Closed by commit rL361647: [clang-tidy] In TransformerClangTidyCheck,
>> require Explanation field. (authored by ymandel, committed by ).
>> Herald added a project: LLVM.
>> Herald added a subscriber: llvm-commits.
>>
>> Changed prior to commit:
>>   https://reviews.llvm.org/D62340?vs=201256&id=201272#toc
>>
>> Repository:
>>   rL LLVM
>>
>> CHANGES SINCE LAST ACTION
>>   https://reviews.llvm.org/D62340/new/
>>
>> https://reviews.llvm.org/D62340
>>
>> Files:
>>   clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
>>   clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
>>
>> clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
>>
>>
>> Index:
>> clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
>> ===
>> --- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
>> +++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
>> @@ -31,10 +31,14 @@
>>  // };
>>  class TransformerClangTidyCheck : public ClangTidyCheck {
>>  public:
>> +  // All cases in \p R must have a non-null \c Explanation, even though
>> \c
>> +  // Explanation is optional for RewriteRule in general. Because the
>> primary
>> +  // purpose of clang-tidy checks is to provide users with diagnostics,
>> we
>> +  // assume that a missing explanation is a bug.  If no explanation is
>> desired,
>> +  // indicate that explicitly (for example, by passing `text("no
>> explanation")`
>> +  //  to `makeRule` as the `Explanation` argument).
>>TransformerClangTidyCheck(tooling::RewriteRule R, StringRef Name,
>> -ClangTidyContext *Context)
>> -  : ClangTidyCheck(Name, Context), Rule(std::move(R)) {}
>> -
>> +ClangTidyContext *Context);
>>void registerMatchers(ast_matchers::MatchFinder *Finder) final;
>>void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
>>
>> Index:
>> clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
>> ===
>> --- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
>> +++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
>> @@ -13,6 +13,17 @@
>>  namespace utils {
>>  using tooling::RewriteRule;
>>
>> +TransformerClangTidyCheck::TransformerClangTidyCheck(tooling::RewriteRule
>> R,
>> + StringRef Name,
>> + ClangTidyContext
>> *Context)
>> +: ClangTidyCheck(Name, Context), Rule(std::move(R)) {
>> +  for (const auto &Case : Rule.Cases) {
>> +assert(Case.Explanation != nullptr &&
>> +   "clang-tidy checks must have an explanation by default;"
>> +   " explicitly provide an empty explanation if none is
>> desired");
>> +  }
>> +}
>> +
>>  void TransformerClangTidyCheck::registerMatchers(
>>  ast_matchers::MatchFinder *Finder) {
>>Finder->addDynamicMatcher(tooling::detail::buildMatcher(Rule), this);
>> @@ -44,15 +55,13 @@
>>if (Transformations->empty())
>>  return;
>>
>> -  StringRef Message = "no explanation";
>> -  if (Case.Explanation) {
>> -if (Expected E = Case.Explanation(Result))
>> -  Message = *E;
>> -else
>> -  llvm::errs() << "Error in explanation: " <<
>> llvm::toString(E.takeError())
>> -   << "\n";
>> +  Expected Explanation = Case.Explanation(Result);
>> +  if (!Explanation) {
>> +llvm::errs() << "Error in explanation: "
>> + << llvm::toString(Explanation.takeError()) << "\n";
>> +return;
>>}
>> -  DiagnosticBuilder Diag = diag(RootLoc, Message);
>> +  DiagnosticBuilder Diag = diag(RootLoc, *Explanation);
>>for (const auto &T : *Transformations) {
>>  Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
>>}
>> Index:
>> clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
>> ===
>> ---
>> clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
>> +++
>> clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
>> @@ -26,15 +26,18 @@
>>using tooling::change;
>>using tooling::node;
>>using tooling::statement;
>> +  using tooling::text;
>>using tooling::stencil:

Re: [PATCH] D62340: [clang-tidy] In TransformerClangTidyCheck, require Explanation field.

2019-05-24 Thread Yitzhak Mandelbaum via cfe-commits
So, it only shows up in Release build, I assume because the assert is left
out:
  for (const auto &Case : Rule.Cases) {
assert(Case.Explanation != nullptr &&
   "clang-tidy checks must have an explanation by default;"
   " explicitly provide an empty explanation if none is desired");
  }
I can think of a few solutions, please let me know if there's a
standard/preferred approach:

1. Use std::all_of.
assert(std::all_of(Rule.Cases.cbegin(), Rule.Cases.cend(), [](const
RewriteRule::Case &C) { return C.Explanation != nullptr; }
   && ...);

2. Trivially use the variable.
I could add a trivial use to the loop
  for (const auto &Case : Rule.Cases) {
+   (void)Case;
assert(Case.Explanation != nullptr &&
   "clang-tidy checks must have an explanation by default;"
   " explicitly provide an empty explanation if none is desired");
  }

3. Use llvm_unreachable instead.
Rewrite the assert to
if (Case.Explanation == nullptr)
  llvm_unreachable(...)

On Fri, May 24, 2019 at 1:16 PM Yitzhak Mandelbaum 
wrote:

> looking now...
>
> On Fri, May 24, 2019 at 12:49 PM Ilya Biryukov 
> wrote:
>
>> This seems to produce warnings about unused variables:
>> …/llvm/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp:20:20:
>> warning: unused variable 'Case' [-Wunused-variable]
>>
>>   for (const auto &Case : Rule.Cases) {
>>
>> Could you take a look?
>>
>> On Fri, May 24, 2019 at 6:29 PM Yitzhak Mandelbaum via Phabricator <
>> revi...@reviews.llvm.org> wrote:
>>
>>> This revision was automatically updated to reflect the committed changes.
>>> Closed by commit rL361647: [clang-tidy] In TransformerClangTidyCheck,
>>> require Explanation field. (authored by ymandel, committed by ).
>>> Herald added a project: LLVM.
>>> Herald added a subscriber: llvm-commits.
>>>
>>> Changed prior to commit:
>>>   https://reviews.llvm.org/D62340?vs=201256&id=201272#toc
>>>
>>> Repository:
>>>   rL LLVM
>>>
>>> CHANGES SINCE LAST ACTION
>>>   https://reviews.llvm.org/D62340/new/
>>>
>>> https://reviews.llvm.org/D62340
>>>
>>> Files:
>>>   clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
>>>   clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
>>>
>>> clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
>>>
>>>
>>> Index:
>>> clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
>>> ===
>>> --- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
>>> +++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
>>> @@ -31,10 +31,14 @@
>>>  // };
>>>  class TransformerClangTidyCheck : public ClangTidyCheck {
>>>  public:
>>> +  // All cases in \p R must have a non-null \c Explanation, even though
>>> \c
>>> +  // Explanation is optional for RewriteRule in general. Because the
>>> primary
>>> +  // purpose of clang-tidy checks is to provide users with diagnostics,
>>> we
>>> +  // assume that a missing explanation is a bug.  If no explanation is
>>> desired,
>>> +  // indicate that explicitly (for example, by passing `text("no
>>> explanation")`
>>> +  //  to `makeRule` as the `Explanation` argument).
>>>TransformerClangTidyCheck(tooling::RewriteRule R, StringRef Name,
>>> -ClangTidyContext *Context)
>>> -  : ClangTidyCheck(Name, Context), Rule(std::move(R)) {}
>>> -
>>> +ClangTidyContext *Context);
>>>void registerMatchers(ast_matchers::MatchFinder *Finder) final;
>>>void check(const ast_matchers::MatchFinder::MatchResult &Result)
>>> final;
>>>
>>> Index:
>>> clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
>>> ===
>>> ---
>>> clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
>>> +++
>>> clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
>>> @@ -13,6 +13,17 @@
>>>  namespace utils {
>>>  using tooling::RewriteRule;
>>>
>>> +TransformerClangTidyCheck::TransformerClangTidyCheck(tooling::RewriteRule
>>> R,
>>> + StringRef Name,
>>> + ClangTidyContext
>>> *Context)
>>> +: ClangTidyCheck(Name, Context), Rule(std::move(R)) {
>>> +  for (const auto &Case : Rule.Cases) {
>>> +assert(Case.Explanation != nullptr &&
>>> +   "clang-tidy checks must have an explanation by default;"
>>> +   " explicitly provide an empty explanation if none is
>>> desired");
>>> +  }
>>> +}
>>> +
>>>  void TransformerClangTidyCheck::registerMatchers(
>>>  ast_matchers::MatchFinder *Finder) {
>>>Finder->addDynamicMatcher(tooling::detail::buildMatcher(Rule), this);
>>> @@ -44,15 +55,13 @@
>>>if (Transformations->empty())
>>>  return;
>>>
>>> -  StringRef Message = "no explanation";
>>> -  if (Case.Explanation) {
>>> -   

Re: [PATCH] D62340: [clang-tidy] In TransformerClangTidyCheck, require Explanation field.

2019-05-24 Thread Yitzhak Mandelbaum via cfe-commits
version 1 here: https://reviews.llvm.org/D62412






On Fri, May 24, 2019 at 1:36 PM Yitzhak Mandelbaum 
wrote:

> So, it only shows up in Release build, I assume because the assert is left
> out:
>   for (const auto &Case : Rule.Cases) {
> assert(Case.Explanation != nullptr &&
>"clang-tidy checks must have an explanation by default;"
>" explicitly provide an empty explanation if none is desired");
>   }
> I can think of a few solutions, please let me know if there's a
> standard/preferred approach:
>
> 1. Use std::all_of.
> assert(std::all_of(Rule.Cases.cbegin(), Rule.Cases.cend(), [](const
> RewriteRule::Case &C) { return C.Explanation != nullptr; }
>&& ...);
>
> 2. Trivially use the variable.
> I could add a trivial use to the loop
>   for (const auto &Case : Rule.Cases) {
> +   (void)Case;
> assert(Case.Explanation != nullptr &&
>"clang-tidy checks must have an explanation by default;"
>" explicitly provide an empty explanation if none is desired");
>   }
>
> 3. Use llvm_unreachable instead.
> Rewrite the assert to
> if (Case.Explanation == nullptr)
>   llvm_unreachable(...)
>
> On Fri, May 24, 2019 at 1:16 PM Yitzhak Mandelbaum 
> wrote:
>
>> looking now...
>>
>> On Fri, May 24, 2019 at 12:49 PM Ilya Biryukov 
>> wrote:
>>
>>> This seems to produce warnings about unused variables:
>>> …/llvm/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp:20:20:
>>> warning: unused variable 'Case' [-Wunused-variable]
>>>
>>>   for (const auto &Case : Rule.Cases) {
>>>
>>> Could you take a look?
>>>
>>> On Fri, May 24, 2019 at 6:29 PM Yitzhak Mandelbaum via Phabricator <
>>> revi...@reviews.llvm.org> wrote:
>>>
 This revision was automatically updated to reflect the committed
 changes.
 Closed by commit rL361647: [clang-tidy] In TransformerClangTidyCheck,
 require Explanation field. (authored by ymandel, committed by ).
 Herald added a project: LLVM.
 Herald added a subscriber: llvm-commits.

 Changed prior to commit:
   https://reviews.llvm.org/D62340?vs=201256&id=201272#toc

 Repository:
   rL LLVM

 CHANGES SINCE LAST ACTION
   https://reviews.llvm.org/D62340/new/

 https://reviews.llvm.org/D62340

 Files:
   clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
   clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h

 clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp


 Index:
 clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
 ===
 --- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
 +++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
 @@ -31,10 +31,14 @@
  // };
  class TransformerClangTidyCheck : public ClangTidyCheck {
  public:
 +  // All cases in \p R must have a non-null \c Explanation, even
 though \c
 +  // Explanation is optional for RewriteRule in general. Because the
 primary
 +  // purpose of clang-tidy checks is to provide users with
 diagnostics, we
 +  // assume that a missing explanation is a bug.  If no explanation is
 desired,
 +  // indicate that explicitly (for example, by passing `text("no
 explanation")`
 +  //  to `makeRule` as the `Explanation` argument).
TransformerClangTidyCheck(tooling::RewriteRule R, StringRef Name,
 -ClangTidyContext *Context)
 -  : ClangTidyCheck(Name, Context), Rule(std::move(R)) {}
 -
 +ClangTidyContext *Context);
void registerMatchers(ast_matchers::MatchFinder *Finder) final;
void check(const ast_matchers::MatchFinder::MatchResult &Result)
 final;

 Index:
 clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
 ===
 ---
 clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
 +++
 clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.cpp
 @@ -13,6 +13,17 @@
  namespace utils {
  using tooling::RewriteRule;

 +TransformerClangTidyCheck::TransformerClangTidyCheck(tooling::RewriteRule
 R,
 + StringRef Name,
 + ClangTidyContext
 *Context)
 +: ClangTidyCheck(Name, Context), Rule(std::move(R)) {
 +  for (const auto &Case : Rule.Cases) {
 +assert(Case.Explanation != nullptr &&
 +   "clang-tidy checks must have an explanation by default;"
 +   " explicitly provide an empty explanation if none is
 desired");
 +  }
 +}
 +
  void TransformerClangTidyCheck::registerMatchers(
  ast_ma

r361955 - [LibTooling] Add `before` and `after` selectors for selecting point-ranges relative to nodes.

2019-05-29 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed May 29 05:40:36 2019
New Revision: 361955

URL: http://llvm.org/viewvc/llvm-project?rev=361955&view=rev
Log:
[LibTooling] Add `before` and `after` selectors for selecting point-ranges 
relative to nodes.

Summary:
The `before` and `after` selectors allow users to specify a zero-length range --
a point -- at the relevant location in an AST-node's source.  Point ranges can
be useful, for example, to insert a change using an API that takes a range to be
modified (e.g. `tooling::change()`).

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62419

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h?rev=361955&r1=361954&r2=361955&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h Wed May 29 
05:40:36 2019
@@ -37,6 +37,15 @@ RangeSelector range(RangeSelector Begin,
 /// Convenience version of \c range where end-points are bound nodes.
 RangeSelector range(std::string BeginID, std::string EndID);
 
+/// Selects the (empty) range [B,B) when \p Selector selects the range [B,E).
+RangeSelector before(RangeSelector Selector);
+
+/// Selects the the point immediately following \p Selector. That is, the
+/// (empty) range [E,E), when \p Selector selects either
+/// * the CharRange [B,E) or
+/// * the TokenRange [B,E'] where the token at E' spans the range [E,E').
+RangeSelector after(RangeSelector Selector);
+
 /// Selects a node, including trailing semicolon (for non-expression
 /// statements). \p ID is the node's binding in the match result.
 RangeSelector node(std::string ID);

Modified: cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp?rev=361955&r1=361954&r2=361955&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp Wed May 29 05:40:36 2019
@@ -104,6 +104,28 @@ static SourceLocation findOpenParen(cons
   return findPreviousTokenKind(EndLoc, SM, LangOpts, tok::TokenKind::l_paren);
 }
 
+RangeSelector tooling::before(RangeSelector Selector) {
+  return [Selector](const MatchResult &Result) -> Expected {
+Expected SelectedRange = Selector(Result);
+if (!SelectedRange)
+  return SelectedRange.takeError();
+return CharSourceRange::getCharRange(SelectedRange->getBegin());
+  };
+}
+
+RangeSelector tooling::after(RangeSelector Selector) {
+  return [Selector](const MatchResult &Result) -> Expected {
+Expected SelectedRange = Selector(Result);
+if (!SelectedRange)
+  return SelectedRange.takeError();
+if (SelectedRange->isCharRange())
+  return CharSourceRange::getCharRange(SelectedRange->getEnd());
+return CharSourceRange::getCharRange(Lexer::getLocForEndOfToken(
+SelectedRange->getEnd(), 0, Result.Context->getSourceManager(),
+Result.Context->getLangOpts()));
+  };
+}
+
 RangeSelector tooling::node(std::string ID) {
   return [ID](const MatchResult &Result) -> Expected {
 Expected Node = getNode(Result.Nodes, ID);

Modified: cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp?rev=361955&r1=361954&r2=361955&view=diff
==
--- cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp Wed May 29 05:40:36 2019
@@ -21,13 +21,15 @@ using namespace tooling;
 using namespace ast_matchers;
 
 namespace {
-using ::testing::AllOf;
-using ::testing::HasSubstr;
-using MatchResult = MatchFinder::MatchResult;
 using ::llvm::Expected;
 using ::llvm::Failed;
 using ::llvm::HasValue;
 using ::llvm::StringError;
+using ::testing::AllOf;
+using ::testing::HasSubstr;
+using ::testing::Property;
+
+using MatchResult = MatchFinder::MatchResult;
 
 struct TestMatch {
   // The AST unit from which `result` is built. We bundle it because it backs
@@ -117,6 +119,55 @@ TEST(RangeSelectorTest, UnboundNode) {
Failed(withUnboundNodeMessage()));
 }
 
+MATCHER_P(EqualsCharSourceRange, Range, "") {
+  return Range.getAsRange() == arg.getAsRange() &&
+ Range.isTokenRange() == arg.isTokenRange();
+}
+
+// FIXME: here and elsewhere: use llvm::Annotations library to explicitly mark
+// points and ranges of interest, enabling more readab

r372129 - [clang-format] Fix cleanup of `AnnotatedLine` to include children nodes.

2019-09-17 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Tue Sep 17 08:10:39 2019
New Revision: 372129

URL: http://llvm.org/viewvc/llvm-project?rev=372129&view=rev
Log:
[clang-format] Fix cleanup of `AnnotatedLine` to include children nodes.

Summary:
AnnotatedLine has a tree structure, and things like the body of a lambda will be
a child of the lambda expression. For example,

[&]() { foo(a); };

will have an AnnotatedLine with a child:

[&]() {};
 '- foo(a);

Currently, when the `Cleaner` class analyzes the affected lines, it does not
cleanup the lines' children nodes, which results in missed cleanup
opportunities, like the lambda body in the example above.

This revision extends the algorithm to visit children, thereby fixing the above 
problem.

Patch by Eric Li.

Reviewers: krasimir

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67659

Modified:
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/unittests/Format/CleanupTest.cpp

Modified: cfe/trunk/lib/Format/Format.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=372129&r1=372128&r2=372129&view=diff
==
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Tue Sep 17 08:10:39 2019
@@ -1417,22 +1417,29 @@ public:
 
 checkEmptyNamespace(AnnotatedLines);
 
-for (auto &Line : AnnotatedLines) {
-  if (Line->Affected) {
-cleanupRight(Line->First, tok::comma, tok::comma);
-cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
-cleanupRight(Line->First, tok::l_paren, tok::comma);
-cleanupLeft(Line->First, tok::comma, tok::r_paren);
-cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
-cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
-cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
-  }
-}
+for (auto *Line : AnnotatedLines)
+  cleanupLine(Line);
 
 return {generateFixes(), 0};
   }
 
 private:
+  void cleanupLine(AnnotatedLine *Line) {
+for (auto *Child : Line->Children) {
+  cleanupLine(Child);
+}
+
+if (Line->Affected) {
+  cleanupRight(Line->First, tok::comma, tok::comma);
+  cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma);
+  cleanupRight(Line->First, tok::l_paren, tok::comma);
+  cleanupLeft(Line->First, tok::comma, tok::r_paren);
+  cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace);
+  cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace);
+  cleanupLeft(Line->First, TT_CtorInitializerColon, tok::equal);
+}
+  }
+
   bool containsOnlyComments(const AnnotatedLine &Line) {
 for (FormatToken *Tok = Line.First; Tok != nullptr; Tok = Tok->Next) {
   if (Tok->isNot(tok::comment))

Modified: cfe/trunk/unittests/Format/CleanupTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/CleanupTest.cpp?rev=372129&r1=372128&r2=372129&view=diff
==
--- cfe/trunk/unittests/Format/CleanupTest.cpp (original)
+++ cfe/trunk/unittests/Format/CleanupTest.cpp Tue Sep 17 08:10:39 2019
@@ -183,10 +183,15 @@ TEST_F(CleanupTest, TrailingCommaInParen
   std::string Code = "int main() { f(,1,,2,3,f(1,2,),4,,);}";
   std::string Expected = "int main() { f(1,2,3,f(1,2),4);}";
   EXPECT_EQ(Expected, cleanupAroundOffsets({15, 18, 29, 33}, Code));
+
+  // Lambda contents are also checked for trailing commas.
+  Code = "int main() { [](){f(,1,,2,3,f(1,2,),4,,);}();}";
+  Expected = "int main() { [](){f(1,2,3,f(1,2),4);}();}";
+  EXPECT_EQ(Expected, cleanupAroundOffsets({20, 23, 34, 38}, Code));
 }
 
 TEST_F(CleanupTest, TrailingCommaInBraces) {
-  // Trainling comma is allowed in brace list.
+  // Trailing comma is allowed in brace list.
   // If there was trailing comma in the original code, then trailing comma is
   // preserved. In this example, element between the last two commas is deleted
   // causing the second-last comma to be redundant.
@@ -194,7 +199,7 @@ TEST_F(CleanupTest, TrailingCommaInBrace
   std::string Expected = "void f() { std::vector v = {1,2,3,}; }";
   EXPECT_EQ(Expected, cleanupAroundOffsets({39}, Code));
 
-  // If there was no trailing comma in the original code, then trainling comma
+  // If there was no trailing comma in the original code, then trailing comma
   // introduced by replacements should be cleaned up. In this example, the
   // element after the last comma is deleted causing the last comma to be
   // redundant.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r372317 - [clang-tidy] Fix bugprone-argument-comment-check to correctly ignore implicit constructors.

2019-09-19 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Sep 19 06:12:05 2019
New Revision: 372317

URL: http://llvm.org/viewvc/llvm-project?rev=372317&view=rev
Log:
[clang-tidy] Fix bugprone-argument-comment-check to correctly ignore implicit 
constructors.

Summary:
After revision 370919, this check incorrectly flags certain cases of implicit
constructors. Specifically, if an argument is annotated with an
argument-comment and the argument expression triggers an implicit constructor,
then the argument comment is associated with argument of the implicit
constructor.

However, this only happens when the constructor has more than one argument.
This revision fixes the check for implicit constructors and adds a regression
test for this case.

Note: r370919 didn't cause this bug, it simply uncovered it by fixing another
bug that was masking the behavior.

Reviewers: gribozavr

Subscribers: xazax.hun, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67744

Modified:
clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp
clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment.cpp

Modified: clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp?rev=372317&r1=372316&r2=372317&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/bugprone/ArgumentCommentCheck.cpp Thu 
Sep 19 06:12:05 2019
@@ -337,7 +337,7 @@ void ArgumentCommentCheck::check(const M
   llvm::makeArrayRef(Call->getArgs(), Call->getNumArgs()));
   } else {
 const auto *Construct = cast(E);
-if (Construct->getNumArgs() == 1 &&
+if (Construct->getNumArgs() > 0 &&
 Construct->getArg(0)->getSourceRange() == Construct->getSourceRange()) 
{
   // Ignore implicit construction.
   return;

Modified: clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment.cpp?rev=372317&r1=372316&r2=372317&view=diff
==
--- clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment.cpp 
(original)
+++ clang-tools-extra/trunk/test/clang-tidy/bugprone-argument-comment.cpp Thu 
Sep 19 06:12:05 2019
@@ -63,6 +63,28 @@ void ignores_underscores() {
   f3(/*With_Underscores=*/false);
 }
 
+namespace IgnoresImplicit {
+struct S {
+  S(int x);
+  int x;
+};
+
+struct T {
+  // Use two arguments (one defaulted) because simplistic check for implicit
+  // constructor looks for only one argument. We need to default the argument 
so
+  // that it will still be triggered implicitly.  This is not contrived -- it
+  // comes up in real code, for example std::set(std::initializer_list...).
+  T(S s, int y = 0);
+};
+
+void k(T arg1);
+
+void mynewtest() {
+  int foo = 3;
+  k(/*arg1=*/S(foo));
+}
+} // namespace IgnoresImplicit
+
 namespace ThisEditDistanceAboveThreshold {
 void f4(int xxx);
 void g() { f4(/*xyz=*/0); }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372410 - [libTooling] Add `ifBound`, `elseBranch` RangeSelector combinators.

2019-09-20 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Sep 20 10:11:03 2019
New Revision: 372410

URL: http://llvm.org/viewvc/llvm-project?rev=372410&view=rev
Log:
[libTooling] Add `ifBound`, `elseBranch` RangeSelector combinators.

Summary:
Adds two new combinators and corresponding tests to the RangeSelector library.
* `ifBound` -- conditional evaluation of range-selectors, based on whether a
   given node id is bound in the match.
* `elseBranch` -- selects the source range of the else and its statement.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67621

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h?rev=372410&r1=372409&r2=372410&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h Fri Sep 20 
10:11:03 2019
@@ -79,10 +79,19 @@ RangeSelector statements(std::string ID)
 // (all source between the braces).
 RangeSelector initListElements(std::string ID);
 
+/// Given an \IfStmt (bound to \p ID), selects the range of the else branch,
+/// starting from the \c else keyword.
+RangeSelector elseBranch(std::string ID);
+
 /// Selects the range from which `S` was expanded (possibly along with other
 /// source), if `S` is an expansion, and `S` itself, otherwise.  Corresponds to
 /// `SourceManager::getExpansionRange`.
 RangeSelector expansion(RangeSelector S);
+
+/// Chooses between the two selectors, based on whether \p ID is bound in the
+/// match.
+RangeSelector ifBound(std::string ID, RangeSelector TrueSelector,
+  RangeSelector FalseSelector);
 } // namespace tooling
 } // namespace clang
 

Modified: cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp?rev=372410&r1=372409&r2=372410&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp Fri Sep 20 10:11:03 2019
@@ -219,6 +219,9 @@ RangeSelector tooling::name(std::string
 }
 
 namespace {
+// FIXME: make this available in the public API for users to easily create 
their
+// own selectors.
+
 // Creates a selector from a range-selection function \p Func, which selects a
 // range that is relative to a bound node id.  \c T is the node type expected 
by
 // \p Func.
@@ -286,6 +289,19 @@ RangeSelector tooling::initListElements(
   return RelativeSelector(std::move(ID));
 }
 
+namespace {
+// Returns the range of the else branch, including the `else` keyword.
+CharSourceRange getElseRange(const MatchResult &Result, const IfStmt &S) {
+  return maybeExtendRange(
+  CharSourceRange::getTokenRange(S.getElseLoc(), S.getEndLoc()),
+  tok::TokenKind::semi, *Result.Context);
+}
+} // namespace
+
+RangeSelector tooling::elseBranch(std::string ID) {
+  return RelativeSelector(std::move(ID));
+}
+
 RangeSelector tooling::expansion(RangeSelector S) {
   return [S](const MatchResult &Result) -> Expected {
 Expected SRange = S(Result);
@@ -294,3 +310,11 @@ RangeSelector tooling::expansion(RangeSe
 return Result.SourceManager->getExpansionRange(*SRange);
   };
 }
+
+RangeSelector tooling::ifBound(std::string ID, RangeSelector TrueSelector,
+   RangeSelector FalseSelector) {
+  return [=](const MatchResult &Result) {
+auto &Map = Result.Nodes.getMap();
+return (Map.find(ID) != Map.end() ? TrueSelector : FalseSelector)(Result);
+  };
+}

Modified: cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp?rev=372410&r1=372409&r2=372410&view=diff
==
--- cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp Fri Sep 20 10:11:03 2019
@@ -520,6 +520,35 @@ TEST(RangeSelectorTest, ElementsOpErrors
Failed(withTypeErrorMessage("stmt")));
 }
 
+TEST(RangeSelectorTest, ElseBranchOpSingleStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+  if (true) x = 3;
+  else x = 4;
+  return x + 5;
+}
+  )cc";
+  StringRef ID = "id";
+  TestMatch Match = matchCode(Code, ifStmt().bind(ID));
+  EXPECT_THAT_EXPECTED(select(elseBranch(ID), Match), HasValue("else x = 4;"));
+}
+
+TEST(RangeSelectorTest, ElseBranchOpCompoundStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+   

r372595 - [libTooling] Introduce new library of source-code builders.

2019-09-23 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Mon Sep 23 05:40:10 2019
New Revision: 372595

URL: http://llvm.org/viewvc/llvm-project?rev=372595&view=rev
Log:
[libTooling] Introduce new library of source-code builders.

Summary:
Introduces facilities for easily building source-code strings, including
idiomatic use of parentheses and the address-of, dereference and member-access
operators (dot and arrow) and queries about need for parentheses.

Reviewers: gribozavr

Subscribers: mgorny, cfe-commits, ilya-biryukov

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67632

Added:
cfe/trunk/include/clang/Tooling/Refactoring/SourceCodeBuilders.h
cfe/trunk/lib/Tooling/Refactoring/SourceCodeBuilders.cpp
cfe/trunk/unittests/Tooling/SourceCodeBuildersTest.cpp
Modified:
cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
cfe/trunk/unittests/Tooling/CMakeLists.txt

Added: cfe/trunk/include/clang/Tooling/Refactoring/SourceCodeBuilders.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/SourceCodeBuilders.h?rev=372595&view=auto
==
--- cfe/trunk/include/clang/Tooling/Refactoring/SourceCodeBuilders.h (added)
+++ cfe/trunk/include/clang/Tooling/Refactoring/SourceCodeBuilders.h Mon Sep 23 
05:40:10 2019
@@ -0,0 +1,86 @@
+//===--- SourceCodeBuilders.h - Source-code building facilities -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// \file
+/// This file collects facilities for generating source code strings.
+///
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_BUILDERS_H_
+#define LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_BUILDERS_H_
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include 
+
+namespace clang {
+namespace tooling {
+
+/// \name Code analysis utilities.
+/// @{
+/// Ignores implicit object-construction expressions in addition to the normal
+/// implicit expressions that are ignored.
+const Expr *reallyIgnoreImplicit(const Expr &E);
+
+/// Determines whether printing this expression in *any* expression requires
+/// parentheses to preserve its meaning. This analyses is necessarily
+/// conservative because it lacks information about the target context.
+bool mayEverNeedParens(const Expr &E);
+
+/// Determines whether printing this expression to the left of a dot or arrow
+/// operator requires a parentheses to preserve its meaning. Given that
+/// dot/arrow are (effectively) the highest precedence, this is equivalent to
+/// asking whether it ever needs parens.
+inline bool needParensBeforeDotOrArrow(const Expr &E) {
+  return mayEverNeedParens(E);
+}
+
+/// Determines whether printing this expression to the right of a unary 
operator
+/// requires a parentheses to preserve its meaning.
+bool needParensAfterUnaryOperator(const Expr &E);
+/// @}
+
+/// \name Basic code-string generation utilities.
+/// @{
+
+/// Builds source for an expression, adding parens if needed for unambiguous
+/// parsing.
+llvm::Optional buildParens(const Expr &E,
+const ASTContext &Context);
+
+/// Builds idiomatic source for the dereferencing of `E`: prefix with `*` but
+/// simplify when it already begins with `&`.  \returns empty string on 
failure.
+llvm::Optional buildDereference(const Expr &E,
+ const ASTContext &Context);
+
+/// Builds idiomatic source for taking the address of `E`: prefix with `&` but
+/// simplify when it already begins with `*`.  \returns empty string on 
failure.
+llvm::Optional buildAddressOf(const Expr &E,
+   const ASTContext &Context);
+
+/// Adds a dot to the end of the given expression, but adds parentheses when
+/// needed by the syntax, and simplifies to `->` when possible, e.g.:
+///
+///  `x` becomes `x.`
+///  `*a` becomes `a->`
+///  `a+b` becomes `(a+b).`
+llvm::Optional buildDot(const Expr &E, const ASTContext &Context);
+
+/// Adds an arrow to the end of the given expression, but adds parentheses
+/// when needed by the syntax, and simplifies to `.` when possible, e.g.:
+///
+///  `x` becomes `x->`
+///  `&a` becomes `a.`
+///  `a+b` becomes `(a+b)->`
+llvm::Optional buildArrow(const Expr &E,
+   const ASTContext &Context);
+/// @}
+
+} // namespace tooling
+} // namespace clang
+#endif // LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_BUILDERS_H_

Modified: cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/CMakeLists.txt?rev=372595&r1=372594&r2=372595&view=diff
==

r372605 - [libTooling] Add `access` and `ifBound` combinators to Stencil library.

2019-09-23 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Mon Sep 23 06:21:42 2019
New Revision: 372605

URL: http://llvm.org/viewvc/llvm-project?rev=372605&view=rev
Log:
[libTooling] Add `access` and `ifBound` combinators to Stencil library.

Summary:
This revision add the `access` and `ifBound` combinators to the Stencil library:
* `access` -- constructs an idiomatic expression for accessing a member (a
  `MemberExpr`).
* `ifBound` -- chooses between two `StencilParts` based on the whether an id is
  bound in the match (corresponds to the combinator of the same name in
  RangeSelector).

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67633

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
cfe/trunk/unittests/Tooling/StencilTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h?rev=372605&r1=372604&r2=372605&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h Mon Sep 23 06:21:42 
2019
@@ -153,6 +153,28 @@ inline StencilPart node(llvm::StringRef
   return selection(tooling::node(Id));
 }
 
+/// Constructs a `MemberExpr` that accesses the named member (\p Member) of the
+/// object bound to \p BaseId. The access is constructed idiomatically: if \p
+/// BaseId is bound to `e` and \p Member identifies member `m`, then returns
+/// `e->m`, when e is a pointer, `e2->m` when e = `*e2` and `e.m` otherwise.
+/// Additionally, `e` is wrapped in parentheses, if needed.
+StencilPart access(llvm::StringRef BaseId, StencilPart Member);
+inline StencilPart access(llvm::StringRef BaseId, llvm::StringRef Member) {
+  return access(BaseId, text(Member));
+}
+
+/// Chooses between the two stencil parts, based on whether \p ID is bound in
+/// the match.
+StencilPart ifBound(llvm::StringRef Id, StencilPart TruePart,
+StencilPart FalsePart);
+
+/// Chooses between the two strings, based on whether \p ID is bound in the
+/// match.
+inline StencilPart ifBound(llvm::StringRef Id, llvm::StringRef TrueText,
+   llvm::StringRef FalseText) {
+  return ifBound(Id, text(TrueText), text(FalseText));
+}
+
 /// For debug use only; semantics are not guaranteed.
 ///
 /// \returns the string resulting from calling the node's print() method.

Modified: cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp?rev=372605&r1=372604&r2=372605&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp Mon Sep 23 06:21:42 2019
@@ -14,6 +14,7 @@
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Tooling/Refactoring/SourceCode.h"
+#include "clang/Tooling/Refactoring/SourceCodeBuilders.h"
 #include "llvm/Support/Errc.h"
 #include 
 #include 
@@ -23,7 +24,9 @@ using namespace clang;
 using namespace tooling;
 
 using ast_matchers::MatchFinder;
+using llvm::errc;
 using llvm::Error;
+using llvm::StringError;
 
 // A down_cast function to safely down cast a StencilPartInterface to a 
subclass
 // D. Returns nullptr if P is not an instance of D.
@@ -51,28 +54,53 @@ struct RawTextData {
 };
 
 // A debugging operation to dump the AST for a particular (bound) AST node.
-struct DebugPrintNodeOpData {
-  explicit DebugPrintNodeOpData(std::string S) : Id(std::move(S)) {}
+struct DebugPrintNodeData {
+  explicit DebugPrintNodeData(std::string S) : Id(std::move(S)) {}
   std::string Id;
 };
 
 // The fragment of code corresponding to the selected range.
-struct SelectorOpData {
-  explicit SelectorOpData(RangeSelector S) : Selector(std::move(S)) {}
+struct SelectorData {
+  explicit SelectorData(RangeSelector S) : Selector(std::move(S)) {}
   RangeSelector Selector;
 };
+
+// A stencil operation to build a member access `e.m` or `e->m`, as 
appropriate.
+struct AccessData {
+  AccessData(StringRef BaseId, StencilPart Member)
+  : BaseId(BaseId), Member(std::move(Member)) {}
+  std::string BaseId;
+  StencilPart Member;
+};
+
+struct IfBoundData {
+  IfBoundData(StringRef Id, StencilPart TruePart, StencilPart FalsePart)
+  : Id(Id), TruePart(std::move(TruePart)), FalsePart(std::move(FalsePart)) 
{
+  }
+  std::string Id;
+  StencilPart TruePart;
+  StencilPart FalsePart;
+};
 } // namespace
 
 bool isEqualData(const RawTextData &A, const RawTextData &B) {
   return A.Text == B.Text;
 }
 
-bool isEqualData(const DebugPrintNodeOpData &A, const DebugPrintNodeOpData &B) 
{
+bool isEqualData(const DebugPrintNodeData &A, const DebugPrintNodeData &B) {
   return A.Id == B.Id;
 }
 
 // Equal

r372870 - [libTooling] Introduce the MatchConsumer abstraction

2019-09-25 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Sep 25 06:34:04 2019
New Revision: 372870

URL: http://llvm.org/viewvc/llvm-project?rev=372870&view=rev
Log:
[libTooling] Introduce the MatchConsumer abstraction

Summary:
This revision introduces a separate (small) library for the `MatchConsumer`
abstraction: computations over AST match results.  This abstraction is central
to the Transformer framework, and there deserves being defined explicitly.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67961

Added:
cfe/trunk/include/clang/Tooling/Refactoring/MatchConsumer.h
Modified:
cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp

Added: cfe/trunk/include/clang/Tooling/Refactoring/MatchConsumer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/MatchConsumer.h?rev=372870&view=auto
==
--- cfe/trunk/include/clang/Tooling/Refactoring/MatchConsumer.h (added)
+++ cfe/trunk/include/clang/Tooling/Refactoring/MatchConsumer.h Wed Sep 25 
06:34:04 2019
@@ -0,0 +1,58 @@
+//===--- MatchConsumer.h - MatchConsumer abstraction *- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// \file This file defines the *MatchConsumer* abstraction: a computation over
+/// match results, specifically the `ast_matchers::MatchFinder::MatchResult`
+/// class.
+///
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_MATCH_CONSUMER_H_
+#define LLVM_CLANG_TOOLING_REFACTOR_MATCH_CONSUMER_H_
+
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace tooling {
+
+/// A failable computation over nodes bound by AST matchers.
+///
+/// The computation should report any errors though its return value (rather
+/// than terminating the program) to enable usage in interactive scenarios like
+/// clang-query.
+///
+/// This is a central abstraction of the Transformer framework.
+template 
+using MatchConsumer =
+std::function(const ast_matchers::MatchFinder::MatchResult &)>;
+
+/// Creates an error that signals that a `MatchConsumer` expected a certain 
node
+/// to be bound by AST matchers, but it was not actually bound.
+inline llvm::Error notBoundError(llvm::StringRef Id) {
+  return llvm::make_error(llvm::errc::invalid_argument,
+ "Id not bound: " + Id);
+}
+
+/// Chooses between the two consumers, based on whether \p ID is bound in the
+/// match.
+template 
+MatchConsumer ifBound(std::string ID, MatchConsumer TrueC,
+ MatchConsumer FalseC) {
+  return [=](const ast_matchers::MatchFinder::MatchResult &Result) {
+auto &Map = Result.Nodes.getMap();
+return (Map.find(ID) != Map.end() ? TrueC : FalseC)(Result);
+  };
+}
+
+} // namespace tooling
+} // namespace clang
+#endif // LLVM_CLANG_TOOLING_REFACTOR_MATCH_CONSUMER_H_

Modified: cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h?rev=372870&r1=372869&r2=372870&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h Wed Sep 25 
06:34:04 2019
@@ -17,14 +17,14 @@
 
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Refactoring/MatchConsumer.h"
 #include "llvm/Support/Error.h"
 #include 
 #include 
 
 namespace clang {
 namespace tooling {
-using RangeSelector = std::function(
-const ast_matchers::MatchFinder::MatchResult &)>;
+using RangeSelector = MatchConsumer;
 
 inline RangeSelector charRange(CharSourceRange R) {
   return [R](const ast_matchers::MatchFinder::MatchResult &)
@@ -87,11 +87,6 @@ RangeSelector elseBranch(std::string ID)
 /// source), if `S` is an expansion, and `S` itself, otherwise.  Corresponds to
 /// `SourceManager::getExpansionRange`.
 RangeSelector expansion(RangeSelector S);
-
-/// Chooses between the two selectors, based on whether \p ID is bound in the
-/// match.
-RangeSelector ifBound(std::string ID, RangeSelector TrueSelector,
-  RangeSelector FalseSelector);
 } // namespace tooling
 } // namespace clang
 

Modified: cfe/trunk/include/clang/Tooling/Refac

r372884 - [NFC] Fix typo in `getPreviousDecl` comment.

2019-09-25 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Sep 25 07:58:39 2019
New Revision: 372884

URL: http://llvm.org/viewvc/llvm-project?rev=372884&view=rev
Log:
[NFC] Fix typo in `getPreviousDecl` comment.

Modified:
cfe/trunk/include/clang/AST/DeclBase.h

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=372884&r1=372883&r2=372884&view=diff
==
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Sep 25 07:58:39 2019
@@ -959,7 +959,7 @@ public:
   /// as this declaration, or NULL if there is no previous declaration.
   Decl *getPreviousDecl() { return getPreviousDeclImpl(); }
 
-  /// Retrieve the most recent declaration that declares the same entity
+  /// Retrieve the previous declaration that declares the same entity
   /// as this declaration, or NULL if there is no previous declaration.
   const Decl *getPreviousDecl() const {
 return const_cast(this)->getPreviousDeclImpl();


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372918 - [libTooling][NFC] Switch StencilTest.cpp to use EXPECT_THAT_EXPECTED

2019-09-25 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Sep 25 13:04:25 2019
New Revision: 372918

URL: http://llvm.org/viewvc/llvm-project?rev=372918&view=rev
Log:
[libTooling][NFC] Switch StencilTest.cpp to use EXPECT_THAT_EXPECTED

Summary:
Currently, some tests use homegrown matchers to handle `llvm::Expected`
values. This revision standardizes on EXPECT_THAT_EXPECTED and `HasValue`.

Reviewers: ilya-biryukov

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67973

Modified:
cfe/trunk/unittests/Tooling/StencilTest.cpp

Modified: cfe/trunk/unittests/Tooling/StencilTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/StencilTest.cpp?rev=372918&r1=372917&r2=372918&view=diff
==
--- cfe/trunk/unittests/Tooling/StencilTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/StencilTest.cpp Wed Sep 25 13:04:25 2019
@@ -31,23 +31,6 @@ using stencil::dPrint;
 using stencil::ifBound;
 using stencil::text;
 
-// In tests, we can't directly match on llvm::Expected since its accessors
-// mutate the object. So, we collapse it to an Optional.
-static llvm::Optional toOptional(llvm::Expected V) {
-  if (V)
-return *V;
-  ADD_FAILURE() << "Losing error in conversion to IsSomething: "
-<< llvm::toString(V.takeError());
-  return llvm::None;
-}
-
-// A very simple matcher for llvm::Optional values.
-MATCHER_P(IsSomething, ValueMatcher, "") {
-  if (!arg)
-return false;
-  return ::testing::ExplainMatchResult(ValueMatcher, *arg, result_listener);
-}
-
 // Create a valid translation-unit from a statement.
 static std::string wrapSnippet(StringRef StatementCode) {
   return ("struct S { int field; }; auto stencil_test_snippet = []{" +
@@ -151,8 +134,8 @@ TEST_F(StencilTest, SingleStatement) {
   // Invert the if-then-else.
   auto Stencil = cat("if (!", node(Condition), ") ", statement(Else), " else ",
  statement(Then));
-  EXPECT_THAT(toOptional(Stencil.eval(StmtMatch->Result)),
-  IsSomething(Eq("if (!true) return 0; else return 1;")));
+  EXPECT_THAT_EXPECTED(Stencil.eval(StmtMatch->Result),
+   HasValue("if (!true) return 0; else return 1;"));
 }
 
 TEST_F(StencilTest, SingleStatementCallOperator) {
@@ -170,8 +153,8 @@ TEST_F(StencilTest, SingleStatementCallO
   // Invert the if-then-else.
   Stencil S = cat("if (!", node(Condition), ") ", statement(Else), " else ",
   statement(Then));
-  EXPECT_THAT(toOptional(S(StmtMatch->Result)),
-  IsSomething(Eq("if (!true) return 0; else return 1;")));
+  EXPECT_THAT_EXPECTED(S(StmtMatch->Result),
+   HasValue("if (!true) return 0; else return 1;"));
 }
 
 TEST_F(StencilTest, UnboundNode) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372936 - [libTooling] Add `run` combinator to Stencils.

2019-09-25 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Sep 25 17:53:56 2019
New Revision: 372936

URL: http://llvm.org/viewvc/llvm-project?rev=372936&view=rev
Log:
[libTooling] Add `run` combinator to Stencils.

Summary:
This revision adds `run`, a StencilPart that runs a user-defined function that
computes a result over `MatchFinder::MatchResult`.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D67969

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
cfe/trunk/unittests/Tooling/StencilTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h?rev=372936&r1=372935&r2=372936&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h Wed Sep 25 17:53:56 
2019
@@ -23,6 +23,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTTypeTraits.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Refactoring/MatchConsumer.h"
 #include "clang/Tooling/Refactoring/RangeSelector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
@@ -175,6 +176,10 @@ inline StencilPart ifBound(llvm::StringR
   return ifBound(Id, text(TrueText), text(FalseText));
 }
 
+/// Wraps a MatchConsumer in a StencilPart, so that it can be used in a 
Stencil.
+/// This supports user-defined extensions to the Stencil language.
+StencilPart run(MatchConsumer C);
+
 /// For debug use only; semantics are not guaranteed.
 ///
 /// \returns the string resulting from calling the node's print() method.

Modified: cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp?rev=372936&r1=372935&r2=372936&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp Wed Sep 25 17:53:56 2019
@@ -26,6 +26,7 @@ using namespace tooling;
 using ast_matchers::MatchFinder;
 using llvm::errc;
 using llvm::Error;
+using llvm::Expected;
 using llvm::StringError;
 
 // A down_cast function to safely down cast a StencilPartInterface to a 
subclass
@@ -102,6 +103,12 @@ bool isEqualData(const IfBoundData &A, c
   return A.Id == B.Id && A.TruePart == B.TruePart && A.FalsePart == 
B.FalsePart;
 }
 
+// Equality is not defined over MatchConsumers, which are opaque.
+bool isEqualData(const MatchConsumer &A,
+ const MatchConsumer &B) {
+  return false;
+}
+
 // The `evalData()` overloads evaluate the given stencil data to a string, 
given
 // the match result, and append it to `Result`. We define an overload for each
 // type of stencil data.
@@ -159,6 +166,15 @@ Error evalData(const IfBoundData &Data,
   .eval(Match, Result);
 }
 
+Error evalData(const MatchConsumer &Fn,
+   const MatchFinder::MatchResult &Match, std::string *Result) {
+  Expected Value = Fn(Match);
+  if (!Value)
+return Value.takeError();
+  *Result += *Value;
+  return Error::success();
+}
+
 template 
 class StencilPartImpl : public StencilPartInterface {
   T Data;
@@ -233,3 +249,9 @@ StencilPart stencil::ifBound(StringRef I
   return StencilPart(std::make_shared>(
   Id, std::move(TruePart), std::move(FalsePart)));
 }
+
+StencilPart stencil::run(MatchConsumer Fn) {
+  return StencilPart(
+  std::make_shared>>(
+  std::move(Fn)));
+}

Modified: cfe/trunk/unittests/Tooling/StencilTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/StencilTest.cpp?rev=372936&r1=372935&r2=372936&view=diff
==
--- cfe/trunk/unittests/Tooling/StencilTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/StencilTest.cpp Wed Sep 25 17:53:56 2019
@@ -29,6 +29,7 @@ using stencil::access;
 using stencil::cat;
 using stencil::dPrint;
 using stencil::ifBound;
+using stencil::run;
 using stencil::text;
 
 // Create a valid translation-unit from a statement.
@@ -283,6 +284,15 @@ TEST_F(StencilTest, AccessOpImplicitThis
   EXPECT_THAT_EXPECTED(Stencil.eval(StmtMatch->Result), HasValue("field"));
 }
 
+TEST_F(StencilTest, RunOp) {
+  StringRef Id = "id";
+  auto SimpleFn = [Id](const MatchResult &R) {
+return std::string(R.Nodes.getNodeAs(Id) != nullptr ? "Bound"
+  : "Unbound");
+  };
+  testExpr(Id, "3;", cat(run(SimpleFn)), "Bound");
+}
+
 TEST(StencilEqualityTest, Equality) {
   auto Lhs = cat("foo", dPrint("dprint_id"));
   auto Rhs = cat("foo", dPrint("dprint_id"));
@@ -307,4 +317,12 @@ TEST(StencilEqualityTest, InEqualitySele
   auto S2 = cat(node("node"));
   EXPECT_NE(S1, S2);
 }
+
+// `run` is

r373093 - [libTooling] Transformer: refine `SourceLocation` specified as anchor of changes.

2019-09-27 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Sep 27 08:26:04 2019
New Revision: 373093

URL: http://llvm.org/viewvc/llvm-project?rev=373093&view=rev
Log:
[libTooling] Transformer: refine `SourceLocation` specified as anchor of 
changes.

Summary: Every change triggered by a rewrite rule is anchored at a particular
location in the source code.  This patch refines how that location is chosen and
defines it as an explicit function so it can be shared by other Transformer
implementations.

This patch was inspired by a bug found by a clang tidy, wherein two changes were
anchored at the same location (the expansion loc of the macro) resulting in the
discarding of the second change.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D66652

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h?rev=373093&r1=373092&r2=373093&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Transformer.h Fri Sep 27 
08:26:04 2019
@@ -251,6 +251,12 @@ ast_matchers::internal::DynTypedMatcher
 std::vector
 buildMatchers(const RewriteRule &Rule);
 
+/// Gets the beginning location of the source matched by a rewrite rule. If the
+/// match occurs within a macro expansion, returns the beginning of the
+/// expansion point. `Result` must come from the matching of a rewrite rule.
+SourceLocation
+getRuleMatchLoc(const ast_matchers::MatchFinder::MatchResult &Result);
+
 /// Returns the \c Case of \c Rule that was selected in the match result.
 /// Assumes a matcher built with \c buildMatcher.
 const RewriteRule::Case &

Modified: cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp?rev=373093&r1=373092&r2=373093&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Transformer.cpp Fri Sep 27 08:26:04 2019
@@ -150,6 +150,21 @@ DynTypedMatcher tooling::detail::buildMa
   return Ms[0];
 }
 
+SourceLocation tooling::detail::getRuleMatchLoc(const MatchResult &Result) {
+  auto &NodesMap = Result.Nodes.getMap();
+  auto Root = NodesMap.find(RewriteRule::RootID);
+  assert(Root != NodesMap.end() && "Transformation failed: missing root 
node.");
+  llvm::Optional RootRange = getRangeForEdit(
+  CharSourceRange::getTokenRange(Root->second.getSourceRange()),
+  *Result.Context);
+  if (RootRange)
+return RootRange->getBegin();
+  // The match doesn't have a coherent range, so fall back to the expansion
+  // location as the "beginning" of the match.
+  return Result.SourceManager->getExpansionLoc(
+  Root->second.getSourceRange().getBegin());
+}
+
 // Finds the case that was "selected" -- that is, whose matcher triggered the
 // `MatchResult`.
 const RewriteRule::Case &
@@ -178,14 +193,6 @@ void Transformer::run(const MatchResult
   if (Result.Context->getDiagnostics().hasErrorOccurred())
 return;
 
-  // Verify the existence and validity of the AST node that roots this rule.
-  auto &NodesMap = Result.Nodes.getMap();
-  auto Root = NodesMap.find(RewriteRule::RootID);
-  assert(Root != NodesMap.end() && "Transformation failed: missing root 
node.");
-  SourceLocation RootLoc = Result.SourceManager->getExpansionLoc(
-  Root->second.getSourceRange().getBegin());
-  assert(RootLoc.isValid() && "Invalid location for Root node of match.");
-
   RewriteRule::Case Case = tooling::detail::findSelectedCase(Result, Rule);
   auto Transformations = tooling::detail::translateEdits(Result, Case.Edits);
   if (!Transformations) {
@@ -195,14 +202,16 @@ void Transformer::run(const MatchResult
 
   if (Transformations->empty()) {
 // No rewrite applied (but no error encountered either).
-RootLoc.print(llvm::errs() << "note: skipping match at loc ",
-  *Result.SourceManager);
+detail::getRuleMatchLoc(Result).print(
+llvm::errs() << "note: skipping match at loc ", *Result.SourceManager);
 llvm::errs() << "\n";
 return;
   }
 
-  // Record the results in the AtomicChange.
-  AtomicChange AC(*Result.SourceManager, RootLoc);
+  // Record the results in the AtomicChange, anchored at the location of the
+  // first change.
+  AtomicChange AC(*Result.SourceManager,
+  (*Transformations)[0].Range.getBegin());
   for (const auto &T : *Transformations) {
 if (auto Err = AC.replace(*Result.SourceManager, T.Range, T.Replacement)) {
   Consumer(std::move(Err));

Modified: cfe/trunk/

r373593 - [libTooling] Add various Stencil combinators for expressions.

2019-10-03 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Thu Oct  3 06:01:00 2019
New Revision: 373593

URL: http://llvm.org/viewvc/llvm-project?rev=373593&view=rev
Log:
[libTooling] Add various Stencil combinators for expressions.

Summary:
This revision adds three new Stencil combinators:
* `expression`, which idiomatically constructs the source for an expression,
  including wrapping the expression's source in parentheses if needed.
* `deref`, which constructs an idiomatic dereferencing expression.
* `addressOf`, which constructs an idiomatic address-taking expression.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D68315

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
cfe/trunk/unittests/Tooling/StencilTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h?rev=373593&r1=373592&r2=373593&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h Thu Oct  3 06:01:00 
2019
@@ -6,7 +6,7 @@
 //
 
//===--===//
 ///
-/// /file
+/// \file
 /// This file defines the *Stencil* abstraction: a code-generating object,
 /// parameterized by named references to (bound) AST nodes.  Given a match
 /// result, a stencil can be evaluated to a string of source code.
@@ -154,6 +154,21 @@ inline StencilPart node(llvm::StringRef
   return selection(tooling::node(Id));
 }
 
+/// Generates the source of the expression bound to \p Id, wrapping it in
+/// parentheses if it may parse differently depending on context. For example, 
a
+/// binary operation is always wrapped, while a variable reference is never
+/// wrapped.
+StencilPart expression(llvm::StringRef Id);
+
+/// Constructs an idiomatic dereferencing of the expression bound to \p ExprId.
+/// \p ExprId is wrapped in parentheses, if needed.
+StencilPart deref(llvm::StringRef ExprId);
+
+/// Constructs an expression that idiomatically takes the address of the
+/// expression bound to \p ExprId. \p ExprId is wrapped in parentheses, if
+/// needed.
+StencilPart addressOf(llvm::StringRef ExprId);
+
 /// Constructs a `MemberExpr` that accesses the named member (\p Member) of the
 /// object bound to \p BaseId. The access is constructed idiomatically: if \p
 /// BaseId is bound to `e` and \p Member identifies member `m`, then returns

Modified: cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp?rev=373593&r1=373592&r2=373593&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp Thu Oct  3 06:01:00 2019
@@ -24,6 +24,7 @@ using namespace clang;
 using namespace tooling;
 
 using ast_matchers::MatchFinder;
+using ast_type_traits::DynTypedNode;
 using llvm::errc;
 using llvm::Error;
 using llvm::Expected;
@@ -37,7 +38,7 @@ template  const D *down_cast
   return static_cast(P);
 }
 
-static llvm::Expected
+static llvm::Expected
 getNode(const ast_matchers::BoundNodes &Nodes, StringRef Id) {
   auto &NodesMap = Nodes.getMap();
   auto It = NodesMap.find(Id);
@@ -60,6 +61,21 @@ struct DebugPrintNodeData {
   std::string Id;
 };
 
+// Operators that take a single node Id as an argument.
+enum class UnaryNodeOperator {
+  Parens,
+  Deref,
+  Address,
+};
+
+// Generic container for stencil operations with a (single) node-id argument.
+struct UnaryOperationData {
+  UnaryOperationData(UnaryNodeOperator Op, std::string Id)
+  : Op(Op), Id(std::move(Id)) {}
+  UnaryNodeOperator Op;
+  std::string Id;
+};
+
 // The fragment of code corresponding to the selected range.
 struct SelectorData {
   explicit SelectorData(RangeSelector S) : Selector(std::move(S)) {}
@@ -91,6 +107,10 @@ bool isEqualData(const DebugPrintNodeDat
   return A.Id == B.Id;
 }
 
+bool isEqualData(const UnaryOperationData &A, const UnaryOperationData &B) {
+  return A.Op == B.Op && A.Id == B.Id;
+}
+
 // Equality is not (yet) defined for \c RangeSelector.
 bool isEqualData(const SelectorData &, const SelectorData &) { return false; }
 
@@ -130,6 +150,32 @@ Error evalData(const DebugPrintNodeData
   return Error::success();
 }
 
+Error evalData(const UnaryOperationData &Data,
+   const MatchFinder::MatchResult &Match, std::string *Result) {
+  const auto *E = Match.Nodes.getNodeAs(Data.Id);
+  if (E == nullptr)
+return llvm::make_error(
+errc::invalid_argument, "Id not bound or not Expr: " + Data.Id);
+  llvm::Optional Source;
+  switch (Data.Op) {
+  case UnaryNodeOperator::Parens:
+Source = buildParens(*E, *Match.Context);
+

r373916 - [libTooling] Add `toString` method to the Stencil class

2019-10-07 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Mon Oct  7 09:20:22 2019
New Revision: 373916

URL: http://llvm.org/viewvc/llvm-project?rev=373916&view=rev
Log:
[libTooling] Add `toString` method to the Stencil class

Summary:
`toString` generates a string representation of the stencil.

Patch by Harshal T. Lehri.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D68574

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
cfe/trunk/unittests/Tooling/StencilTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h?rev=373916&r1=373915&r2=373916&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/Stencil.h Mon Oct  7 09:20:22 
2019
@@ -50,6 +50,11 @@ public:
 
   virtual bool isEqual(const StencilPartInterface &other) const = 0;
 
+  /// Constructs a string representation of the StencilPart. StencilParts
+  /// generated by the `selection` and `run` functions do not have a unique
+  /// string representation.
+  virtual std::string toString() const = 0;
+
   const void *typeId() const { return TypeId; }
 
 protected:
@@ -86,6 +91,12 @@ public:
 return Impl->isEqual(*Other.Impl);
   }
 
+  std::string toString() const {
+if (Impl == nullptr)
+  return "";
+return Impl->toString();
+  }
+
 private:
   std::shared_ptr Impl;
 };
@@ -120,6 +131,16 @@ public:
 return eval(Result);
   }
 
+  /// Constructs a string representation of the Stencil. The string is not
+  /// guaranteed to be unique.
+  std::string toString() const {
+std::vector PartStrings;
+PartStrings.reserve(Parts.size());
+for (const auto &Part : Parts)
+  PartStrings.push_back(Part.toString());
+return llvm::join(PartStrings, ", ");
+  }
+
 private:
   friend bool operator==(const Stencil &A, const Stencil &B);
   static StencilPart wrap(llvm::StringRef Text);

Modified: cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp?rev=373916&r1=373915&r2=373916&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Stencil.cpp Mon Oct  7 09:20:22 2019
@@ -15,6 +15,7 @@
 #include "clang/Lex/Lexer.h"
 #include "clang/Tooling/Refactoring/SourceCode.h"
 #include "clang/Tooling/Refactoring/SourceCodeBuilders.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/Errc.h"
 #include 
 #include 
@@ -128,6 +129,54 @@ bool isEqualData(const MatchConsumer &) {
+  return "MatchConsumer()";
+}
+
 // The `evalData()` overloads evaluate the given stencil data to a string, 
given
 // the match result, and append it to `Result`. We define an overload for each
 // type of stencil data.
@@ -247,6 +296,8 @@ public:
   return isEqualData(Data, OtherPtr->Data);
 return false;
   }
+
+  std::string toString() const override { return toStringData(Data); }
 };
 } // namespace
 

Modified: cfe/trunk/unittests/Tooling/StencilTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/StencilTest.cpp?rev=373916&r1=373915&r2=373916&view=diff
==
--- cfe/trunk/unittests/Tooling/StencilTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/StencilTest.cpp Mon Oct  7 09:20:22 2019
@@ -389,4 +389,59 @@ TEST(StencilEqualityTest, InEqualityRun)
   auto S2 = cat(run(F));
   EXPECT_NE(S1, S2);
 }
+
+TEST(StencilToStringTest, RawTextOp) {
+  auto S = cat("foo bar baz");
+  EXPECT_EQ(S.toString(), R"("foo bar baz")");
+}
+
+TEST(StencilToStringTest, RawTextOpEscaping) {
+  auto S = cat("foo \"bar\" baz\\n");
+  EXPECT_EQ(S.toString(), R"("foo \"bar\" baz\\n")");
+}
+
+TEST(StencilToStringTest, DebugPrintNodeOp) {
+  auto S = cat(dPrint("Id"));
+  EXPECT_EQ(S.toString(), R"repr(dPrint("Id"))repr");
+}
+
+TEST(StencilToStringTest, ExpressionOp) {
+  auto S = cat(expression("Id"));
+  EXPECT_EQ(S.toString(), R"repr(expression("Id"))repr");
+}
+
+TEST(StencilToStringTest, DerefOp) {
+  auto S = cat(deref("Id"));
+  EXPECT_EQ(S.toString(), R"repr(deref("Id"))repr");
+}
+
+TEST(StencilToStringTest, AddressOfOp) {
+  auto S = cat(addressOf("Id"));
+  EXPECT_EQ(S.toString(), R"repr(addressOf("Id"))repr");
+}
+
+TEST(StencilToStringTest, AccessOp) {
+  auto S = cat(access("Id", text("memberData")));
+  EXPECT_EQ(S.toString(), R"repr(access("Id", "memberData"))repr");
+}
+
+TEST(StencilToStringTest, AccessOpStencilPart) {
+  auto S = cat(access("Id", access("subId", "memberData")));
+  EXPECT_EQ(S.toString(),
+R"repr(access("Id", access("subId", "memberData")))repr");
+}
+
+TEST(St

r373928 - [libTooling][NFC] Fix build break in r373916.

2019-10-07 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Mon Oct  7 10:24:23 2019
New Revision: 373928

URL: http://llvm.org/viewvc/llvm-project?rev=373928&view=rev
Log:
[libTooling][NFC] Fix build break in r373916.

r373916 used raw strings inside macro calls, which breaks some builds.

Modified:
cfe/trunk/unittests/Tooling/StencilTest.cpp

Modified: cfe/trunk/unittests/Tooling/StencilTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/StencilTest.cpp?rev=373928&r1=373927&r2=373928&view=diff
==
--- cfe/trunk/unittests/Tooling/StencilTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/StencilTest.cpp Mon Oct  7 10:24:23 2019
@@ -392,56 +392,64 @@ TEST(StencilEqualityTest, InEqualityRun)
 
 TEST(StencilToStringTest, RawTextOp) {
   auto S = cat("foo bar baz");
-  EXPECT_EQ(S.toString(), R"("foo bar baz")");
+  StringRef Expected = R"("foo bar baz")";
+  EXPECT_EQ(S.toString(), Expected);
 }
 
 TEST(StencilToStringTest, RawTextOpEscaping) {
   auto S = cat("foo \"bar\" baz\\n");
-  EXPECT_EQ(S.toString(), R"("foo \"bar\" baz\\n")");
+  StringRef Expected = R"("foo \"bar\" baz\\n")";
+  EXPECT_EQ(S.toString(), Expected);
 }
 
 TEST(StencilToStringTest, DebugPrintNodeOp) {
   auto S = cat(dPrint("Id"));
-  EXPECT_EQ(S.toString(), R"repr(dPrint("Id"))repr");
+  StringRef Expected = R"repr(dPrint("Id"))repr";
+  EXPECT_EQ(S.toString(), Expected);
 }
 
 TEST(StencilToStringTest, ExpressionOp) {
   auto S = cat(expression("Id"));
-  EXPECT_EQ(S.toString(), R"repr(expression("Id"))repr");
+  StringRef Expected = R"repr(expression("Id"))repr";
+  EXPECT_EQ(S.toString(), Expected);
 }
 
 TEST(StencilToStringTest, DerefOp) {
   auto S = cat(deref("Id"));
-  EXPECT_EQ(S.toString(), R"repr(deref("Id"))repr");
+  StringRef Expected = R"repr(deref("Id"))repr";
+  EXPECT_EQ(S.toString(), Expected);
 }
 
 TEST(StencilToStringTest, AddressOfOp) {
   auto S = cat(addressOf("Id"));
-  EXPECT_EQ(S.toString(), R"repr(addressOf("Id"))repr");
+  StringRef Expected = R"repr(addressOf("Id"))repr";
+  EXPECT_EQ(S.toString(), Expected);
 }
 
 TEST(StencilToStringTest, AccessOp) {
   auto S = cat(access("Id", text("memberData")));
-  EXPECT_EQ(S.toString(), R"repr(access("Id", "memberData"))repr");
+  StringRef Expected = R"repr(access("Id", "memberData"))repr";
+  EXPECT_EQ(S.toString(), Expected);
 }
 
 TEST(StencilToStringTest, AccessOpStencilPart) {
   auto S = cat(access("Id", access("subId", "memberData")));
-  EXPECT_EQ(S.toString(),
-R"repr(access("Id", access("subId", "memberData")))repr");
+  StringRef Expected = R"repr(access("Id", access("subId", 
"memberData")))repr";
+  EXPECT_EQ(S.toString(), Expected);
 }
 
 TEST(StencilToStringTest, IfBoundOp) {
   auto S = cat(ifBound("Id", text("trueText"), access("exprId", 
"memberData")));
-  EXPECT_EQ(
-  S.toString(),
-  R"repr(ifBound("Id", "trueText", access("exprId", "memberData")))repr");
+  StringRef Expected =
+  R"repr(ifBound("Id", "trueText", access("exprId", "memberData")))repr";
+  EXPECT_EQ(S.toString(), Expected);
 }
 
 TEST(StencilToStringTest, MultipleOp) {
   auto S = cat("foo", access("x", "m()"), "bar",
ifBound("x", text("t"), access("e", "f")));
-  EXPECT_EQ(S.toString(), R"repr("foo", access("x", "m()"), "bar", )repr"
-  R"repr(ifBound("x", "t", access("e", "f")))repr");
+  StringRef Expected = R"repr("foo", access("x", "m()"), "bar", )repr"
+   R"repr(ifBound("x", "t", access("e", "f")))repr";
+  EXPECT_EQ(S.toString(), Expected);
 }
 } // namespace


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r374271 - [libTooling] Move Transformer files to their own directory/library.

2019-10-09 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Oct  9 19:34:47 2019
New Revision: 374271

URL: http://llvm.org/viewvc/llvm-project?rev=374271&view=rev
Log:
[libTooling] Move Transformer files to their own directory/library.

Summary:
The Transformer library has been growing inside of
lib/Tooling/Refactoring. However, it's not really related to anything else in
that directory. This revision moves all Transformer-related files into their own
include & lib directories.  A followup revision will (temporarily) add
forwarding headers to help any users migrate their code to the new location.

Reviewers: gribozavr

Subscribers: mgorny, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D68637

Modified:
clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt

clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp

Modified: clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt?rev=374271&r1=374270&r2=374271&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/utils/CMakeLists.txt Wed Oct  9 19:34:47 
2019
@@ -23,5 +23,5 @@ add_clang_library(clangTidyUtils
   clangBasic
   clangLex
   clangTidy
-  clangToolingRefactoring
+  clangTransformer
   )

Modified: clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h?rev=374271&r1=374270&r2=374271&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h 
(original)
+++ clang-tools-extra/trunk/clang-tidy/utils/TransformerClangTidyCheck.h Wed 
Oct  9 19:34:47 2019
@@ -13,7 +13,7 @@
 #include "../utils/IncludeInserter.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/Tooling/Refactoring/Transformer.h"
+#include "clang/Tooling/Transformer/Transformer.h"
 #include 
 #include 
 

Modified: clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt?rev=374271&r1=374270&r2=374271&view=diff
==
--- clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/CMakeLists.txt Wed Oct  9 
19:34:47 2019
@@ -31,7 +31,7 @@ clang_target_link_libraries(ClangTidyTes
   clangSerialization
   clangTooling
   clangToolingCore
-  clangToolingRefactoring
+  clangTransformer
   )
 target_link_libraries(ClangTidyTests
   PRIVATE

Modified: 
clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp?rev=374271&r1=374270&r2=374271&view=diff
==
--- 
clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp 
(original)
+++ 
clang-tools-extra/trunk/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp 
Wed Oct  9 19:34:47 2019
@@ -9,9 +9,9 @@
 #include "../clang-tidy/utils/TransformerClangTidyCheck.h"
 #include "ClangTidyTest.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/Tooling/Refactoring/RangeSelector.h"
-#include "clang/Tooling/Refactoring/Stencil.h"
-#include "clang/Tooling/Refactoring/Transformer.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "clang/Tooling/Transformer/Stencil.h"
+#include "clang/Tooling/Transformer/Transformer.h"
 #include "gtest/gtest.h"
 
 namespace clang {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r374552 - [libTooling] Change Stencil equality to use `toString()`

2019-10-11 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Oct 11 07:02:03 2019
New Revision: 374552

URL: http://llvm.org/viewvc/llvm-project?rev=374552&view=rev
Log:
[libTooling] Change Stencil equality to use `toString()`

Summary:
Removes the `isEqual` method from StencilPartInterface and modifies equality to
use the string representation returned by the `toString` method for comparison.

This means the `run` and `selection` stencils return true by default, and
clients should be cautious in relying on equality operator for comparison of
stencils containing parts generated by these functions.

It also means we no longer need the custom RTTI support (typeId() and
down_cast()), so it has been removed.

Patch by Harshal T. Lehri.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D68825

Modified:
cfe/trunk/include/clang/Tooling/Transformer/Stencil.h
cfe/trunk/lib/Tooling/Transformer/Stencil.cpp
cfe/trunk/unittests/Tooling/StencilTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Transformer/Stencil.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Transformer/Stencil.h?rev=374552&r1=374551&r2=374552&view=diff
==
--- cfe/trunk/include/clang/Tooling/Transformer/Stencil.h (original)
+++ cfe/trunk/include/clang/Tooling/Transformer/Stencil.h Fri Oct 11 07:02:03 
2019
@@ -48,26 +48,18 @@ public:
   virtual llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &Match,
std::string *Result) const = 0;
 
-  virtual bool isEqual(const StencilPartInterface &other) const = 0;
-
   /// Constructs a string representation of the StencilPart. StencilParts
   /// generated by the `selection` and `run` functions do not have a unique
   /// string representation.
   virtual std::string toString() const = 0;
 
-  const void *typeId() const { return TypeId; }
-
 protected:
-  StencilPartInterface(const void *DerivedId) : TypeId(DerivedId) {}
+  StencilPartInterface() = default;
 
   // Since this is an abstract class, copying/assigning only make sense for
   // derived classes implementing `clone()`.
   StencilPartInterface(const StencilPartInterface &) = default;
   StencilPartInterface &operator=(const StencilPartInterface &) = default;
-
-  /// Unique identifier of the concrete type of this instance.  Supports safe
-  /// downcasting.
-  const void *TypeId;
 };
 
 /// A copyable facade for a std::unique_ptr. Copies 
result
@@ -83,14 +75,6 @@ public:
 return Impl->eval(Match, Result);
   }
 
-  bool operator==(const StencilPart &Other) const {
-if (Impl == Other.Impl)
-  return true;
-if (Impl == nullptr || Other.Impl == nullptr)
-  return false;
-return Impl->isEqual(*Other.Impl);
-  }
-
   std::string toString() const {
 if (Impl == nullptr)
   return "";
@@ -142,7 +126,6 @@ public:
   }
 
 private:
-  friend bool operator==(const Stencil &A, const Stencil &B);
   static StencilPart wrap(llvm::StringRef Text);
   static StencilPart wrap(RangeSelector Selector);
   static StencilPart wrap(StencilPart Part) { return Part; }
@@ -150,12 +133,6 @@ private:
   std::vector Parts;
 };
 
-inline bool operator==(const Stencil &A, const Stencil &B) {
-  return A.Parts == B.Parts;
-}
-
-inline bool operator!=(const Stencil &A, const Stencil &B) { return !(A == B); 
}
-
 // Functions for conveniently building stencils.
 namespace stencil {
 /// Convenience wrapper for Stencil::cat that can be imported with a using 
decl.

Modified: cfe/trunk/lib/Tooling/Transformer/Stencil.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Transformer/Stencil.cpp?rev=374552&r1=374551&r2=374552&view=diff
==
--- cfe/trunk/lib/Tooling/Transformer/Stencil.cpp (original)
+++ cfe/trunk/lib/Tooling/Transformer/Stencil.cpp Fri Oct 11 07:02:03 2019
@@ -31,14 +31,6 @@ using llvm::Error;
 using llvm::Expected;
 using llvm::StringError;
 
-// A down_cast function to safely down cast a StencilPartInterface to a 
subclass
-// D. Returns nullptr if P is not an instance of D.
-template  const D *down_cast(const StencilPartInterface *P) {
-  if (P == nullptr || D::typeId() != P->typeId())
-return nullptr;
-  return static_cast(P);
-}
-
 static llvm::Expected
 getNode(const ast_matchers::BoundNodes &Nodes, StringRef Id) {
   auto &NodesMap = Nodes.getMap();
@@ -100,35 +92,6 @@ struct IfBoundData {
   StencilPart FalsePart;
 };
 
-bool isEqualData(const RawTextData &A, const RawTextData &B) {
-  return A.Text == B.Text;
-}
-
-bool isEqualData(const DebugPrintNodeData &A, const DebugPrintNodeData &B) {
-  return A.Id == B.Id;
-}
-
-bool isEqualData(const UnaryOperationData &A, const UnaryOperationData &B) {
-  return A.Op == B.Op && A.Id == B.Id;
-}
-
-// Equality is not (yet) defined for \c RangeSelector.
-bool isEqualData(const SelectorData &, const SelectorData &) { r

r374558 - [libTooling] Move `RewriteRule` abstraction into its own header and impl.

2019-10-11 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Oct 11 07:43:46 2019
New Revision: 374558

URL: http://llvm.org/viewvc/llvm-project?rev=374558&view=rev
Log:
[libTooling] Move `RewriteRule` abstraction into its own header and impl.

Summary: Move the `RewriteRule` class and related declarations into its own set
of files (header, implementation). Only the `Transformer` class is left in the
Transformer-named files. This change clarifies the distinction between the
`RewriteRule` class, which is essential to the Transformer library, and the
`Transformer` class, which is only one possible `RewriteRule` interpreter
(compare to `TransformerClangTidyCheck`, a clang-tidy based interpreter).

Reviewers: gribozavr

Subscribers: jfb, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D68795

Added:
cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h
cfe/trunk/lib/Tooling/Transformer/RewriteRule.cpp
Modified:
cfe/trunk/include/clang/Tooling/Transformer/Transformer.h
cfe/trunk/lib/Tooling/Transformer/CMakeLists.txt
cfe/trunk/lib/Tooling/Transformer/Transformer.cpp

Added: cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h?rev=374558&view=auto
==
--- cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h (added)
+++ cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h Fri Oct 11 
07:43:46 2019
@@ -0,0 +1,288 @@
+//===--- RewriteRule.h - RewriteRule class --*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+///  \file
+///  Defines the RewriteRule class and related functions for creating,
+///  modifying and interpreting RewriteRules.
+///
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_TRANSFORMER_REWRITE_RULE_H_
+#define LLVM_CLANG_TOOLING_TRANSFORMER_REWRITE_RULE_H_
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "clang/Tooling/Transformer/MatchConsumer.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+
+namespace clang {
+namespace tooling {
+using TextGenerator = MatchConsumer;
+
+/// Wraps a string as a TextGenerator.
+inline TextGenerator text(std::string M) {
+  return [M](const ast_matchers::MatchFinder::MatchResult &)
+ -> Expected { return M; };
+}
+
+// Description of a source-code edit, expressed in terms of an AST node.
+// Includes: an ID for the (bound) node, a selector for source related to the
+// node, a replacement and, optionally, an explanation for the edit.
+//
+// * Target: the source code impacted by the rule. This identifies an AST node,
+//   or part thereof (\c Part), whose source range indicates the extent of the
+//   replacement applied by the replacement term.  By default, the extent is 
the
+//   node matched by the pattern term (\c NodePart::Node). Target's are typed
+//   (\c Kind), which guides the determination of the node extent.
+//
+// * Replacement: a function that produces a replacement string for the target,
+//   based on the match result.
+//
+// * Note: (optional) a note specifically for this edit, potentially 
referencing
+//   elements of the match.  This will be displayed to the user, where 
possible;
+//   for example, in clang-tidy diagnostics.  Use of notes should be rare --
+//   explanations of the entire rewrite should be set in the rule
+//   (`RewriteRule::Explanation`) instead.  Notes serve the rare cases wherein
+//   edit-specific diagnostics are required.
+//
+// `ASTEdit` should be built using the `change` convenience functions. For
+// example,
+// \code
+//   change(name(fun), text("Frodo"))
+// \endcode
+// Or, if we use Stencil for the TextGenerator:
+// \code
+//   using stencil::cat;
+//   change(statement(thenNode), cat("{", thenNode, "}"))
+//   change(callArgs(call), cat(x, ",", y))
+// \endcode
+// Or, if you are changing the node corresponding to the rule's matcher, you 
can
+// use the single-argument override of \c change:
+// \code
+//   change(cat("different_expr"))
+// \endcode
+struct ASTEdit {
+  RangeSelector TargetRange;
+  TextGenerator Replacement;
+  TextGenerator Note;
+};
+
+/// Format of the path in an include directive -- angle brackets or quotes.
+enum class IncludeFormat {
+  Quoted,
+  Angled,
+};
+
+/// Description of a source-code transformation.
+//
+// A *rewrit

r374962 - [libTooling] Put all Transformer declarations in a single namespace.

2019-10-15 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Tue Oct 15 18:06:46 2019
New Revision: 374962

URL: http://llvm.org/viewvc/llvm-project?rev=374962&view=rev
Log:
[libTooling] Put all Transformer declarations in a single namespace.

Summary:
This revision introduces a new namespace, `clang::transformer`, to hold
the declarations for the Transformer library.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D68876

Modified:
cfe/trunk/include/clang/Tooling/Transformer/MatchConsumer.h
cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h
cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h
cfe/trunk/include/clang/Tooling/Transformer/Stencil.h
cfe/trunk/include/clang/Tooling/Transformer/Transformer.h
cfe/trunk/lib/Tooling/Transformer/RangeSelector.cpp
cfe/trunk/lib/Tooling/Transformer/RewriteRule.cpp
cfe/trunk/lib/Tooling/Transformer/Stencil.cpp
cfe/trunk/lib/Tooling/Transformer/Transformer.cpp
cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
cfe/trunk/unittests/Tooling/StencilTest.cpp
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Transformer/MatchConsumer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Transformer/MatchConsumer.h?rev=374962&r1=374961&r2=374962&view=diff
==
--- cfe/trunk/include/clang/Tooling/Transformer/MatchConsumer.h (original)
+++ cfe/trunk/include/clang/Tooling/Transformer/MatchConsumer.h Tue Oct 15 
18:06:46 2019
@@ -22,8 +22,7 @@
 #include "llvm/Support/Error.h"
 
 namespace clang {
-namespace tooling {
-
+namespace transformer {
 /// A failable computation over nodes bound by AST matchers.
 ///
 /// The computation should report any errors though its return value (rather
@@ -52,7 +51,12 @@ MatchConsumer ifBound(std::string ID,
 return (Map.find(ID) != Map.end() ? TrueC : FalseC)(Result);
   };
 }
+} // namespace transformer
 
+namespace tooling {
+// DEPRECATED: Temporary alias supporting client migration to the `transformer`
+// namespace.
+using transformer::ifBound;
 } // namespace tooling
 } // namespace clang
 #endif // LLVM_CLANG_TOOLING_TRANSFORMER_MATCH_CONSUMER_H_

Modified: cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h?rev=374962&r1=374961&r2=374962&view=diff
==
--- cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h (original)
+++ cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h Tue Oct 15 
18:06:46 2019
@@ -23,7 +23,7 @@
 #include 
 
 namespace clang {
-namespace tooling {
+namespace transformer {
 using RangeSelector = MatchConsumer;
 
 inline RangeSelector charRange(CharSourceRange R) {
@@ -87,6 +87,24 @@ RangeSelector elseBranch(std::string ID)
 /// source), if `S` is an expansion, and `S` itself, otherwise.  Corresponds to
 /// `SourceManager::getExpansionRange`.
 RangeSelector expansion(RangeSelector S);
+} // namespace transformer
+
+namespace tooling {
+// DEPRECATED: These are temporary aliases supporting client migration to the
+// `transformer` namespace.
+using transformer::after;
+using transformer::before;
+using transformer::callArgs;
+using transformer::charRange;
+using transformer::elseBranch;
+using transformer::expansion;
+using transformer::initListElements;
+using transformer::member;
+using transformer::name;
+using transformer::node;
+using transformer::range;
+using transformer::statement;
+using transformer::statements;
 } // namespace tooling
 } // namespace clang
 

Modified: cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h?rev=374962&r1=374961&r2=374962&view=diff
==
--- cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h (original)
+++ cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h Tue Oct 15 
18:06:46 2019
@@ -29,9 +29,8 @@
 #include 
 
 namespace clang {
-namespace tooling {
+namespace transformer {
 using TextGenerator = MatchConsumer;
-
 /// Wraps a string as a TextGenerator.
 inline TextGenerator text(std::string M) {
   return [M](const ast_matchers::MatchFinder::MatchResult &)
@@ -282,6 +281,24 @@ Expected>
 translateEdits(const ast_matchers::MatchFinder::MatchResult &Result,
llvm::ArrayRef Edits);
 } // namespace detail
+} // namespace transformer
+
+namespace tooling {
+// DEPRECATED: These are temporary aliases supporting client migration to the
+// `transformer` namespace.
+using transformer::addInclude;
+using transformer::applyFirst;
+using transformer::change;
+using transformer::insertAfter;
+using transformer::insertBefore;
+using transformer::makeRule;
+using transfo

r375003 - [libTooling] Fix r374962: add more Transformer forwarding decls.

2019-10-16 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Wed Oct 16 07:26:20 2019
New Revision: 375003

URL: http://llvm.org/viewvc/llvm-project?rev=375003&view=rev
Log:
[libTooling] Fix r374962: add more Transformer forwarding decls.

Summary:
The move to a new, single namespace in r374962 left out some type definitions
from the old namespace and resulted in one naming conflict (`text`).  This
revision adds aliases for those definitions and removes one of the `text`
functions from the new namespace.

Reviewers: alexfh

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D69036

Modified:
cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h
cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h
cfe/trunk/include/clang/Tooling/Transformer/Stencil.h
cfe/trunk/unittests/Tooling/TransformerTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h?rev=375003&r1=375002&r2=375003&view=diff
==
--- cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h (original)
+++ cfe/trunk/include/clang/Tooling/Transformer/RangeSelector.h Wed Oct 16 
07:26:20 2019
@@ -92,6 +92,8 @@ RangeSelector expansion(RangeSelector S)
 namespace tooling {
 // DEPRECATED: These are temporary aliases supporting client migration to the
 // `transformer` namespace.
+using RangeSelector = transformer::RangeSelector;
+
 using transformer::after;
 using transformer::before;
 using transformer::callArgs;

Modified: cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h?rev=375003&r1=375002&r2=375003&view=diff
==
--- cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h (original)
+++ cfe/trunk/include/clang/Tooling/Transformer/RewriteRule.h Wed Oct 16 
07:26:20 2019
@@ -31,11 +31,6 @@
 namespace clang {
 namespace transformer {
 using TextGenerator = MatchConsumer;
-/// Wraps a string as a TextGenerator.
-inline TextGenerator text(std::string M) {
-  return [M](const ast_matchers::MatchFinder::MatchResult &)
- -> Expected { return M; };
-}
 
 // Description of a source-code edit, expressed in terms of an AST node.
 // Includes: an ID for the (bound) node, a selector for source related to the
@@ -221,7 +216,9 @@ inline ASTEdit insertAfter(RangeSelector
 
 /// Removes the source selected by \p S.
 inline ASTEdit remove(RangeSelector S) {
-  return change(std::move(S), text(""));
+  return change(std::move(S),
+[](const ast_matchers::MatchFinder::MatchResult &)
+-> Expected { return ""; });
 }
 
 /// The following three functions are a low-level part of the RewriteRule
@@ -286,6 +283,14 @@ translateEdits(const ast_matchers::Match
 namespace tooling {
 // DEPRECATED: These are temporary aliases supporting client migration to the
 // `transformer` namespace.
+/// Wraps a string as a TextGenerator.
+using TextGenerator = transformer::TextGenerator;
+
+inline TextGenerator text(std::string M) {
+  return [M](const ast_matchers::MatchFinder::MatchResult &)
+ -> Expected { return M; };
+}
+
 using transformer::addInclude;
 using transformer::applyFirst;
 using transformer::change;
@@ -293,7 +298,6 @@ using transformer::insertAfter;
 using transformer::insertBefore;
 using transformer::makeRule;
 using transformer::remove;
-using transformer::text;
 using transformer::RewriteRule;
 using transformer::IncludeFormat;
 namespace detail {

Modified: cfe/trunk/include/clang/Tooling/Transformer/Stencil.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Transformer/Stencil.h?rev=375003&r1=375002&r2=375003&view=diff
==
--- cfe/trunk/include/clang/Tooling/Transformer/Stencil.h (original)
+++ cfe/trunk/include/clang/Tooling/Transformer/Stencil.h Wed Oct 16 07:26:20 
2019
@@ -195,9 +195,11 @@ StencilPart dPrint(llvm::StringRef Id);
 } // namespace transformer
 
 namespace tooling {
-namespace stencil {
 // DEPRECATED: These are temporary aliases supporting client migration to the
 // `transformer` namespace.
+using Stencil = transformer::Stencil;
+using StencilPart = transformer::StencilPart;
+namespace stencil {
 using transformer::access;
 using transformer::addressOf;
 using transformer::cat;

Modified: cfe/trunk/unittests/Tooling/TransformerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/TransformerTest.cpp?rev=375003&r1=375002&r2=375003&view=diff
==
--- cfe/trunk/unittests/Tooling/TransformerTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/TransformerTest.cpp Wed Oct 16 07:26:20 2019
@@ -21,

[clang] 396bbae - [libTooling][NFC]Fix typo in comment in RangeSelectors

2020-05-21 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-05-21T16:13:02-04:00
New Revision: 396bbae41604637008bd5102e1d02d4543f1c3c9

URL: 
https://github.com/llvm/llvm-project/commit/396bbae41604637008bd5102e1d02d4543f1c3c9
DIFF: 
https://github.com/llvm/llvm-project/commit/396bbae41604637008bd5102e1d02d4543f1c3c9.diff

LOG: [libTooling][NFC]Fix typo in comment in RangeSelectors
Fixes transposed names in comment.

Added: 


Modified: 
clang/include/clang/Tooling/Transformer/RangeSelector.h

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/RangeSelector.h 
b/clang/include/clang/Tooling/Transformer/RangeSelector.h
index 9f556d206321..eaab3fc4c0c7 100644
--- a/clang/include/clang/Tooling/Transformer/RangeSelector.h
+++ b/clang/include/clang/Tooling/Transformer/RangeSelector.h
@@ -43,7 +43,7 @@ RangeSelector before(RangeSelector Selector);
 /// Selects the the point immediately following \p Selector. That is, the
 /// (empty) range [E,E), when \p Selector selects either
 /// * the CharRange [B,E) or
-/// * the TokenRange [B,E'] where the token at E' spans the range [E,E').
+/// * the TokenRange [B,E'] where the token at E' spans the range [E',E).
 RangeSelector after(RangeSelector Selector);
 
 /// Selects a node, including trailing semicolon (for non-expression



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ff2743b - [libTooling] In Transformer, allow atomic changes to span multiple files.

2020-05-26 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-05-26T09:17:35-04:00
New Revision: ff2743bf047deac7ef6cc6c3efd30ff05e55b2ad

URL: 
https://github.com/llvm/llvm-project/commit/ff2743bf047deac7ef6cc6c3efd30ff05e55b2ad
DIFF: 
https://github.com/llvm/llvm-project/commit/ff2743bf047deac7ef6cc6c3efd30ff05e55b2ad.diff

LOG: [libTooling] In Transformer, allow atomic changes to span multiple files.

Summary:
Currently, all changes returned by a single application of a rule must fit in
one atomic change and therefore must apply to one file. However, there are
patterns in which a single rule will want to modify multiple files; for example,
a header and implementation to change a declaration and its definition. This
patch relaxes Transformer, libTooling's interpreter of RewriteRules, to support
multiple changes.

Reviewers: gribozavr

Subscribers: mgrang, jfb, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D80239

Added: 


Modified: 
clang/lib/Tooling/Transformer/Transformer.cpp
clang/unittests/Tooling/TransformerTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Transformer/Transformer.cpp 
b/clang/lib/Tooling/Transformer/Transformer.cpp
index 93c2c0912d21..71340bf2f676 100644
--- a/clang/lib/Tooling/Transformer/Transformer.cpp
+++ b/clang/lib/Tooling/Transformer/Transformer.cpp
@@ -12,6 +12,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Tooling/Refactoring/AtomicChange.h"
 #include "llvm/Support/Error.h"
+#include 
 #include 
 #include 
 
@@ -45,28 +46,39 @@ void Transformer::run(const MatchFinder::MatchResult 
&Result) {
 return;
   }
 
-  // Record the results in the AtomicChange, anchored at the location of the
-  // first change.
-  AtomicChange AC(*Result.SourceManager,
-  (*Transformations)[0].Range.getBegin());
+  // Group the transformations, by file, into AtomicChanges, each anchored by
+  // the location of the first change in that file.
+  std::map ChangesByFileID;
   for (const auto &T : *Transformations) {
+auto ID = Result.SourceManager->getFileID(T.Range.getBegin());
+auto Iter = ChangesByFileID
+.emplace(ID, AtomicChange(*Result.SourceManager,
+  T.Range.getBegin()))
+.first;
+auto &AC = Iter->second;
 if (auto Err = AC.replace(*Result.SourceManager, T.Range, T.Replacement)) {
   Consumer(std::move(Err));
   return;
 }
   }
 
-  for (const auto &I : Case.AddedIncludes) {
-auto &Header = I.first;
-switch (I.second) {
-case transformer::IncludeFormat::Quoted:
-  AC.addHeader(Header);
-  break;
-case transformer::IncludeFormat::Angled:
-  AC.addHeader((llvm::Twine("<") + Header + ">").str());
-  break;
+  for (auto &IDChangePair : ChangesByFileID) {
+auto &AC = IDChangePair.second;
+// FIXME: this will add includes to *all* changed files, which may not be
+// the intent. We should upgrade the representation to allow associating
+// headers with specific edits.
+for (const auto &I : Case.AddedIncludes) {
+  auto &Header = I.first;
+  switch (I.second) {
+  case transformer::IncludeFormat::Quoted:
+AC.addHeader(Header);
+break;
+  case transformer::IncludeFormat::Angled:
+AC.addHeader((llvm::Twine("<") + Header + ">").str());
+break;
+  }
 }
-  }
 
-  Consumer(std::move(AC));
+Consumer(std::move(AC));
+  }
 }

diff  --git a/clang/unittests/Tooling/TransformerTest.cpp 
b/clang/unittests/Tooling/TransformerTest.cpp
index 1d955cf5e9b8..c8c6db059fed 100644
--- a/clang/unittests/Tooling/TransformerTest.cpp
+++ b/clang/unittests/Tooling/TransformerTest.cpp
@@ -817,4 +817,46 @@ TEST(TransformerDeathTest, OrderedRuleTypes) {
"Matcher must be.*node matcher");
 }
 #endif
+
+// Edits are able to span multiple files; in this case, a header and an
+// implementation file.
+TEST_F(TransformerTest, MultipleFiles) {
+  std::string Header = R"cc(void RemoveThisFunction();)cc";
+  std::string Source = R"cc(#include "input.h"
+void RemoveThisFunction();)cc";
+  Transformer T(
+  makeRule(functionDecl(hasName("RemoveThisFunction")), changeTo(cat(""))),
+  consumer());
+  T.registerMatchers(&MatchFinder);
+  auto Factory = newFrontendActionFactory(&MatchFinder);
+  EXPECT_TRUE(runToolOnCodeWithArgs(
+  Factory->create(), Source, std::vector(), "input.cc",
+  "clang-tool", std::make_shared(),
+  {{"input.h", Header}}));
+
+  std::sort(Changes.begin(), Changes.end(),
+[](const AtomicChange &L, const AtomicChange &R) {
+  return L.getFilePath() < R.getFilePath();
+});
+
+  ASSERT_EQ(Changes[0].getFilePath(), "./input.h");
+  EXPECT_THAT(Changes[0].getInsertedHeaders(), IsEmpty());
+  EXPECT_THAT(Changes[0].getRemovedHeaders(), IsEmpty());
+  llvm::Expected 

[clang] 04a96aa - [ASTMatchers] Add traversal-kind support to `DynTypedMatcher`

2020-05-28 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-05-28T11:18:37-04:00
New Revision: 04a96aa3e430a66767732f44acea00c6e13c9f78

URL: 
https://github.com/llvm/llvm-project/commit/04a96aa3e430a66767732f44acea00c6e13c9f78
DIFF: 
https://github.com/llvm/llvm-project/commit/04a96aa3e430a66767732f44acea00c6e13c9f78.diff

LOG: [ASTMatchers] Add traversal-kind support to `DynTypedMatcher`

Summary:
This patch exposes `TraversalKind` support in the `DynTypedMatcher` API. While
previously, the `match` method supported traversal logic, it was not possible to
set or get the traversal kind.

Reviewers: gribozavr, steveire

Subscribers: hokein, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D80685

Added: 


Modified: 
clang/include/clang/ASTMatchers/ASTMatchersInternal.h
clang/lib/ASTMatchers/ASTMatchersInternal.cpp
clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
clang/unittests/ASTMatchers/CMakeLists.txt

Removed: 




diff  --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h 
b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index e363bdd9ae9c..ac8469bded53 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -395,6 +395,12 @@ class DynTypedMatcher {
   ///   restricts the node types for \p Kind.
   DynTypedMatcher dynCastTo(const ASTNodeKind Kind) const;
 
+  /// Return a matcher that that points to the same implementation, but sets 
the
+  ///   traversal kind.
+  ///
+  /// If the traversal kind is already set, then \c TK overrides it.
+  DynTypedMatcher withTraversalKind(TraversalKind TK);
+
   /// Returns true if the matcher matches the given \c DynNode.
   bool matches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder) const;
@@ -458,6 +464,14 @@ class DynTypedMatcher {
   /// If it is not compatible, then this matcher will never match anything.
   template  Matcher unconditionalConvertTo() const;
 
+  /// Returns the \c TraversalKind respected by calls to `match()`, if any.
+  ///
+  /// Most matchers will not have a traversal kind set, instead relying on the
+  /// surrounding context. For those, \c llvm::None is returned.
+  llvm::Optional getTraversalKind() const {
+return Implementation->TraversalKind();
+  }
+
 private:
   DynTypedMatcher(ASTNodeKind SupportedKind, ASTNodeKind RestrictKind,
   IntrusiveRefCntPtr Implementation)

diff  --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp 
b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index 40bd439f79fa..1ee89ccd3c11 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -136,6 +136,31 @@ class TrueMatcherImpl : public DynMatcherInterface {
   }
 };
 
+/// A matcher that specifies a particular \c TraversalKind.
+///
+/// The kind provided to the constructor overrides any kind that may be
+/// specified by the `InnerMatcher`.
+class DynTraversalMatcherImpl : public DynMatcherInterface {
+public:
+  explicit DynTraversalMatcherImpl(
+  clang::TraversalKind TK,
+  IntrusiveRefCntPtr InnerMatcher)
+  : TK(TK), InnerMatcher(std::move(InnerMatcher)) {}
+
+  bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder,
+  BoundNodesTreeBuilder *Builder) const override {
+return this->InnerMatcher->dynMatches(DynNode, Finder, Builder);
+  }
+
+  llvm::Optional TraversalKind() const override {
+return TK;
+  }
+
+private:
+  clang::TraversalKind TK;
+  IntrusiveRefCntPtr InnerMatcher;
+};
+
 } // namespace
 
 static llvm::ManagedStatic TrueMatcherInstance;
@@ -204,6 +229,14 @@ DynTypedMatcher::constructRestrictedWrapper(const 
DynTypedMatcher &InnerMatcher,
   return Copy;
 }
 
+DynTypedMatcher
+DynTypedMatcher::withTraversalKind(ast_type_traits::TraversalKind TK) {
+  auto Copy = *this;
+  Copy.Implementation =
+  new DynTraversalMatcherImpl(TK, std::move(Copy.Implementation));
+  return Copy;
+}
+
 DynTypedMatcher DynTypedMatcher::trueMatcher(ASTNodeKind NodeKind) {
   return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance);
 }

diff  --git a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp 
b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
index 0d0f0307e7f1..2886481ea262 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -13,10 +13,12 @@
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/Host.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
 #include "gtest/gtest.h"
 
 namespace clang {
 namespace ast_matchers {
+using internal::DynTypedMatcher;
 
 #if GTEST_HAS_DEATH_TEST
 TEST(HasNameDeathTest, DiesOnEmptyName) {
@@ -171,6 +173,26 @@ TEST(Matcher, matchOverEntireASTContext) {
   EXPECT_NE(nullptr, PT);
 }
 
+TEST(DynTyp

[clang] ce5780b - [libTooling] Fix Transformer to work with ambient traversal kinds.

2020-05-28 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-05-28T11:42:07-04:00
New Revision: ce5780b88c6e2f3303afd266e5e29c1badd9eb3b

URL: 
https://github.com/llvm/llvm-project/commit/ce5780b88c6e2f3303afd266e5e29c1badd9eb3b
DIFF: 
https://github.com/llvm/llvm-project/commit/ce5780b88c6e2f3303afd266e5e29c1badd9eb3b.diff

LOG: [libTooling] Fix Transformer to work with ambient traversal kinds.

Summary:
`RewriteRule`'s `applyFirst` was brittle with respect to the default setting of 
the
`TraversalKind`. This patch builds awareness of traversal kinds directly into
rewrite rules so that they are insensitive to any changes in defaults.

Reviewers: steveire, gribozavr

Subscribers: hokein, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D80606

Added: 


Modified: 
clang/include/clang/Tooling/Transformer/RewriteRule.h
clang/lib/Tooling/Transformer/RewriteRule.cpp
clang/unittests/Tooling/TransformerTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h 
b/clang/include/clang/Tooling/Transformer/RewriteRule.h
index 4a5e5556cdff..0a961ccc475d 100644
--- a/clang/include/clang/Tooling/Transformer/RewriteRule.h
+++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h
@@ -273,11 +273,13 @@ namespace detail {
 /// supports mixing matchers of 
diff erent kinds.
 ast_matchers::internal::DynTypedMatcher buildMatcher(const RewriteRule &Rule);
 
-/// Builds a set of matchers that cover the rule (one for each distinct node
-/// matcher base kind: Stmt, Decl, etc.). Node-matchers for `QualType` and
-/// `Type` are not permitted, since such nodes carry no source location
-/// information and are therefore not relevant for rewriting. If any such
-/// matchers are included, will return an empty vector.
+/// Builds a set of matchers that cover the rule.
+///
+/// One matcher is built for each distinct node matcher base kind: Stmt, Decl,
+/// etc. Node-matchers for `QualType` and `Type` are not permitted, since such
+/// nodes carry no source location information and are therefore not relevant
+/// for rewriting. If any such matchers are included, will return an empty
+/// vector.
 std::vector
 buildMatchers(const RewriteRule &Rule);
 

diff  --git a/clang/lib/Tooling/Transformer/RewriteRule.cpp 
b/clang/lib/Tooling/Transformer/RewriteRule.cpp
index 968f7fa6cd32..ddce6ce59185 100644
--- a/clang/lib/Tooling/Transformer/RewriteRule.cpp
+++ b/clang/lib/Tooling/Transformer/RewriteRule.cpp
@@ -116,10 +116,13 @@ static bool hasValidKind(const DynTypedMatcher &M) {
 #endif
 
 // Binds each rule's matcher to a unique (and deterministic) tag based on
-// `TagBase` and the id paired with the case.
+// `TagBase` and the id paired with the case. All of the returned matchers have
+// their traversal kind explicitly set, either based on a pre-set kind or to 
the
+// provided `DefaultTraversalKind`.
 static std::vector taggedMatchers(
 StringRef TagBase,
-const SmallVectorImpl> &Cases) {
+const SmallVectorImpl> &Cases,
+ast_type_traits::TraversalKind DefaultTraversalKind) {
   std::vector Matchers;
   Matchers.reserve(Cases.size());
   for (const auto &Case : Cases) {
@@ -127,8 +130,10 @@ static std::vector taggedMatchers(
 // HACK: Many matchers are not bindable, so ensure that tryBind will work.
 DynTypedMatcher BoundMatcher(Case.second.Matcher);
 BoundMatcher.setAllowBind(true);
-auto M = BoundMatcher.tryBind(Tag);
-Matchers.push_back(*std::move(M));
+auto M = *BoundMatcher.tryBind(Tag);
+Matchers.push_back(!M.getTraversalKind()
+   ? M.withTraversalKind(DefaultTraversalKind)
+   : std::move(M));
   }
   return Matchers;
 }
@@ -158,14 +163,21 @@ transformer::detail::buildMatchers(const RewriteRule 
&Rule) {
 Buckets[Cases[I].Matcher.getSupportedKind()].emplace_back(I, Cases[I]);
   }
 
+  // Each anyOf explicitly controls the traversal kind. The anyOf itself is set
+  // to `TK_AsIs` to ensure no nodes are skipped, thereby deferring to the kind
+  // of the branches. Then, each branch is either left as is, if the kind is
+  // already set, or explicitly set to `TK_IgnoreUnlessSpelledInSource`. We
+  // choose this setting, because we think it is the one most friendly to
+  // beginners, who are (largely) the target audience of Transformer.
   std::vector Matchers;
   for (const auto &Bucket : Buckets) {
 DynTypedMatcher M = DynTypedMatcher::constructVariadic(
 DynTypedMatcher::VO_AnyOf, Bucket.first,
-taggedMatchers("Tag", Bucket.second));
+taggedMatchers("Tag", Bucket.second, TK_IgnoreUnlessSpelledInSource));
 M.setAllowBind(true);
 // `tryBind` is guaranteed to succeed, because `AllowBind` was set to true.
-Matchers.push_back(*M.tryBind(RewriteRule::RootID));
+Matchers.push_back(
+M.tryBind(RewriteRule::RootID)->withTraversalKind(TK_AsIs));
   }
   r

[clang-tools-extra] 7cfdff7 - [clang-tidy] Add abseil-string-find-str-contains checker.

2020-05-28 Thread Yitzhak Mandelbaum via cfe-commits

Author: Tom Lokovic
Date: 2020-05-28T12:35:57-04:00
New Revision: 7cfdff7b4a6704b8ef2a1b594e1ec19d2d89f385

URL: 
https://github.com/llvm/llvm-project/commit/7cfdff7b4a6704b8ef2a1b594e1ec19d2d89f385
DIFF: 
https://github.com/llvm/llvm-project/commit/7cfdff7b4a6704b8ef2a1b594e1ec19d2d89f385.diff

LOG: [clang-tidy] Add abseil-string-find-str-contains checker.

Summary: This adds a checker which suggests replacing string.find(...) == npos 
with absl::StrContains.

Reviewers: alexfh, hokein, aaron.ballman, njames93, ymandel

Reviewed By: ymandel

Subscribers: ymandel, Eugene.Zelenko, xazax.hun, mgorny, Charusso, phosek, 
cfe-commits

Tags: #clang, #clang-tools-extra

Differential Revision: https://reviews.llvm.org/D80023

Added: 
clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp
clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.h
clang-tools-extra/docs/clang-tidy/checks/abseil-string-find-str-contains.rst

clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp

Modified: 
clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp
clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp 
b/clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp
index c70ef9007fbd..7d592d7e3e55 100644
--- a/clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/abseil/AbseilTidyModule.cpp
@@ -21,8 +21,9 @@
 #include "NoInternalDependenciesCheck.h"
 #include "NoNamespaceCheck.h"
 #include "RedundantStrcatCallsCheck.h"
-#include "StringFindStartswithCheck.h"
 #include "StrCatAppendCheck.h"
+#include "StringFindStartswithCheck.h"
+#include "StringFindStrContainsCheck.h"
 #include "TimeComparisonCheck.h"
 #include "TimeSubtractionCheck.h"
 #include "UpgradeDurationConversionsCheck.h"
@@ -61,6 +62,8 @@ class AbseilModule : public ClangTidyModule {
 "abseil-str-cat-append");
 CheckFactories.registerCheck(
 "abseil-string-find-startswith");
+CheckFactories.registerCheck(
+"abseil-string-find-str-contains");
 CheckFactories.registerCheck(
 "abseil-time-comparison");
 CheckFactories.registerCheck(

diff  --git a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
index bd8865ef9269..c4efa0fe2743 100644
--- a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
@@ -20,6 +20,7 @@ add_clang_library(clangTidyAbseilModule
   RedundantStrcatCallsCheck.cpp
   StrCatAppendCheck.cpp
   StringFindStartswithCheck.cpp
+  StringFindStrContainsCheck.cpp
   TimeComparisonCheck.cpp
   TimeSubtractionCheck.cpp
   UpgradeDurationConversionsCheck.cpp

diff  --git 
a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp 
b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp
new file mode 100644
index ..f60ce2000766
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp
@@ -0,0 +1,110 @@
+//===--- StringFindStrContainsCheck.cc - 
clang-tidy===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "StringFindStrContainsCheck.h"
+
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Tooling/Transformer/RewriteRule.h"
+#include "clang/Tooling/Transformer/Stencil.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+using ::clang::transformer::applyFirst;
+using ::clang::transformer::cat;
+using ::clang::transformer::change;
+using ::clang::transformer::makeRule;
+using ::clang::transformer::node;
+
+static const char DefaultStringLikeClasses[] = "::std::basic_string;"
+   "::std::basic_string_view;"
+   "::absl::string_view";
+static const char DefaultAbseilStringsMatchHeader[] = "absl/strings/match.h";
+
+static llvm::Optional
+MakeRule(const LangOptions &LangOpts,
+ const ClangTidyCheck::OptionsView &Options) {
+  // Parse options.
+  //
+  // FIXME(tdl-g): These options are being parsed redundantly with the
+  // constructor because TransformerClangTidyCheck forces us to provide 
MakeRule
+  // before "this" is fully constructed, but StoreOptions requires us to store
+  // the parsed options in "this".  We need to fix Transf

[clang-tools-extra] a1b88af - [clang-tidy] Fix build broken by commit 7cfdff7b4a6704b8ef2a1b594e1ec19d2d89f385 (D80023)

2020-05-28 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-05-28T13:39:58-04:00
New Revision: a1b88afe46d7a0f72d2acd8792951bd959b27545

URL: 
https://github.com/llvm/llvm-project/commit/a1b88afe46d7a0f72d2acd8792951bd959b27545
DIFF: 
https://github.com/llvm/llvm-project/commit/a1b88afe46d7a0f72d2acd8792951bd959b27545.diff

LOG: [clang-tidy] Fix build broken by commit 
7cfdff7b4a6704b8ef2a1b594e1ec19d2d89f385 (D80023)

Added: 


Modified: 
clang-tools-extra/clang-tidy/abseil/CMakeLists.txt

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
index c4efa0fe2743..5926717c6c0a 100644
--- a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt
@@ -33,4 +33,5 @@ add_clang_library(clangTidyAbseilModule
   clangTidy
   clangTidyUtils
   clangTooling
+  clangTransformer
   )



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] c0b8954 - [libTooling] In Clang Transformer, change `Metadata` field to deferred evalutaion

2020-07-20 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-07-20T21:17:09Z
New Revision: c0b8954ecba500e3d9609152295b74ccd7d89d62

URL: 
https://github.com/llvm/llvm-project/commit/c0b8954ecba500e3d9609152295b74ccd7d89d62
DIFF: 
https://github.com/llvm/llvm-project/commit/c0b8954ecba500e3d9609152295b74ccd7d89d62.diff

LOG: [libTooling] In Clang Transformer, change `Metadata` field to deferred 
evalutaion

`Metadata` is being changed from an `llvm::Any` to a 
`MatchConsumer`, so that it's evaluation can be be dependent on 
`MatchResult`s passed in.

Reviewed By: ymandel, gribozavr2

Differential Revision: https://reviews.llvm.org/D83820

Added: 


Modified: 
clang/include/clang/Tooling/Transformer/RewriteRule.h
clang/lib/Tooling/Transformer/RewriteRule.cpp
clang/unittests/Tooling/TransformerTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h 
b/clang/include/clang/Tooling/Transformer/RewriteRule.h
index d9e68717d5c8..eb6947b54885 100644
--- a/clang/include/clang/Tooling/Transformer/RewriteRule.h
+++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h
@@ -47,6 +47,8 @@ using EditGenerator = MatchConsumer>;
 
 using TextGenerator = std::shared_ptr>;
 
+using AnyGenerator = MatchConsumer;
+
 // Description of a source-code edit, expressed in terms of an AST node.
 // Includes: an ID for the (bound) node, a selector for source related to the
 // node, a replacement and, optionally, an explanation for the edit.
@@ -87,7 +89,11 @@ struct ASTEdit {
   RangeSelector TargetRange;
   TextGenerator Replacement;
   TextGenerator Note;
-  llvm::Any Metadata;
+  // Not all transformations will want or need to attach metadata and therefore
+  // should not be required to do so.
+  AnyGenerator Metadata = [](const ast_matchers::MatchFinder::MatchResult &) {
+return llvm::Any();
+  };
 };
 
 /// Lifts a list of `ASTEdit`s into an `EditGenerator`.
@@ -261,9 +267,27 @@ inline ASTEdit insertAfter(RangeSelector S, TextGenerator 
Replacement) {
 /// Removes the source selected by \p S.
 ASTEdit remove(RangeSelector S);
 
-inline ASTEdit withMetadata(ASTEdit edit, llvm::Any Metadata) {
-  edit.Metadata = std::move(Metadata);
-  return edit;
+// FIXME: If `Metadata` returns an `llvm::Expected` the `AnyGenerator` will
+// construct an `llvm::Expected` where no error is present but the
+// `llvm::Any` holds the error. This is unlikely but potentially surprising.
+// Perhaps the `llvm::Expected` should be unwrapped, or perhaps this should be 
a
+// compile-time error. No solution here is perfect.
+//
+// Note: This function template accepts any type callable with a MatchResult
+// rather than a `std::function` because the return-type needs to be deduced. 
If
+// it accepted a `std::function`, lambdas or other callable
+// types would not be able to deduce `R`, and users would be forced to specify
+// explicitly the type they intended to return by wrapping the lambda at the
+// call-site.
+template 
+inline ASTEdit withMetadata(ASTEdit Edit, Callable Metadata) {
+  Edit.Metadata =
+  [Gen = std::move(Metadata)](
+  const ast_matchers::MatchFinder::MatchResult &R) -> llvm::Any {
+return Gen(R);
+  };
+
+  return Edit;
 }
 
 /// The following three functions are a low-level part of the RewriteRule

diff  --git a/clang/lib/Tooling/Transformer/RewriteRule.cpp 
b/clang/lib/Tooling/Transformer/RewriteRule.cpp
index 995bec03cd66..a212a868c81d 100644
--- a/clang/lib/Tooling/Transformer/RewriteRule.cpp
+++ b/clang/lib/Tooling/Transformer/RewriteRule.cpp
@@ -44,10 +44,13 @@ translateEdits(const MatchResult &Result, ArrayRef 
ASTEdits) {
 auto Replacement = E.Replacement->eval(Result);
 if (!Replacement)
   return Replacement.takeError();
+auto Metadata = E.Metadata(Result);
+if (!Metadata)
+  return Metadata.takeError();
 transformer::Edit T;
 T.Range = *EditRange;
 T.Replacement = std::move(*Replacement);
-T.Metadata = E.Metadata;
+T.Metadata = std::move(*Metadata);
 Edits.push_back(std::move(T));
   }
   return Edits;

diff  --git a/clang/unittests/Tooling/TransformerTest.cpp 
b/clang/unittests/Tooling/TransformerTest.cpp
index 7d6b63293748..59b334b0ea5a 100644
--- a/clang/unittests/Tooling/TransformerTest.cpp
+++ b/clang/unittests/Tooling/TransformerTest.cpp
@@ -440,6 +440,12 @@ TEST_F(TransformerTest, RemoveEdit) {
 }
 
 TEST_F(TransformerTest, WithMetadata) {
+  auto makeMetadata = [](const MatchFinder::MatchResult &R) -> llvm::Any {
+int N =
+R.Nodes.getNodeAs("int")->getValue().getLimitedValue();
+return N;
+  };
+
   std::string Input = R"cc(
 int f() {
   int x = 5;
@@ -448,8 +454,11 @@ TEST_F(TransformerTest, WithMetadata) {
   )cc";
 
   Transformer T(
-  makeRule(declStmt().bind("decl"),
-   withMetadata(remove(statement(std::string("decl"))), 17)),
+  makeRule(
+  declStmt(containsDeclaration

[Differential] D83820: Change metadata to deferred evalutaion in Clang Transformer.

2020-07-20 Thread Yitzhak Mandelbaum via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc0b8954ecba5: [libTooling] In Clang Transformer, change 
`Metadata` field to deferred… (authored by ymandel).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83820/new/


  https://reviews.llvm.org/D83820

Files:
  clang/include/clang/Tooling/Transformer/RewriteRule.h
  clang/lib/Tooling/Transformer/RewriteRule.cpp
  clang/unittests/Tooling/TransformerTest.cpp

Index: clang/unittests/Tooling/TransformerTest.cpp
===
--- clang/unittests/Tooling/TransformerTest.cpp
+++ clang/unittests/Tooling/TransformerTest.cpp
@@ -440,6 +440,12 @@
 }
 
 TEST_F(TransformerTest, WithMetadata) {
+  auto makeMetadata = [](const MatchFinder::MatchResult &R) -> llvm::Any {
+int N =
+R.Nodes.getNodeAs("int")->getValue().getLimitedValue();
+return N;
+  };
+
   std::string Input = R"cc(
 int f() {
   int x = 5;
@@ -448,8 +454,11 @@
   )cc";
 
   Transformer T(
-  makeRule(declStmt().bind("decl"),
-   withMetadata(remove(statement(std::string("decl"))), 17)),
+  makeRule(
+  declStmt(containsDeclaration(0, varDecl(hasInitializer(
+  integerLiteral().bind("int")
+  .bind("decl"),
+  withMetadata(remove(statement(std::string("decl"))), makeMetadata)),
   consumer());
   T.registerMatchers(&MatchFinder);
   auto Factory = newFrontendActionFactory(&MatchFinder);
@@ -459,7 +468,7 @@
   ASSERT_EQ(Changes.size(), 1u);
   const llvm::Any &Metadata = Changes[0].getMetadata();
   ASSERT_TRUE(llvm::any_isa(Metadata));
-  EXPECT_THAT(llvm::any_cast(Metadata), 17);
+  EXPECT_THAT(llvm::any_cast(Metadata), 5);
 }
 
 TEST_F(TransformerTest, MultiChange) {
Index: clang/lib/Tooling/Transformer/RewriteRule.cpp
===
--- clang/lib/Tooling/Transformer/RewriteRule.cpp
+++ clang/lib/Tooling/Transformer/RewriteRule.cpp
@@ -44,10 +44,13 @@
 auto Replacement = E.Replacement->eval(Result);
 if (!Replacement)
   return Replacement.takeError();
+auto Metadata = E.Metadata(Result);
+if (!Metadata)
+  return Metadata.takeError();
 transformer::Edit T;
 T.Range = *EditRange;
 T.Replacement = std::move(*Replacement);
-T.Metadata = E.Metadata;
+T.Metadata = std::move(*Metadata);
 Edits.push_back(std::move(T));
   }
   return Edits;
Index: clang/include/clang/Tooling/Transformer/RewriteRule.h
===
--- clang/include/clang/Tooling/Transformer/RewriteRule.h
+++ clang/include/clang/Tooling/Transformer/RewriteRule.h
@@ -47,6 +47,8 @@
 
 using TextGenerator = std::shared_ptr>;
 
+using AnyGenerator = MatchConsumer;
+
 // Description of a source-code edit, expressed in terms of an AST node.
 // Includes: an ID for the (bound) node, a selector for source related to the
 // node, a replacement and, optionally, an explanation for the edit.
@@ -87,7 +89,11 @@
   RangeSelector TargetRange;
   TextGenerator Replacement;
   TextGenerator Note;
-  llvm::Any Metadata;
+  // Not all transformations will want or need to attach metadata and therefore
+  // should not be required to do so.
+  AnyGenerator Metadata = [](const ast_matchers::MatchFinder::MatchResult &) {
+return llvm::Any();
+  };
 };
 
 /// Lifts a list of `ASTEdit`s into an `EditGenerator`.
@@ -261,9 +267,27 @@
 /// Removes the source selected by \p S.
 ASTEdit remove(RangeSelector S);
 
-inline ASTEdit withMetadata(ASTEdit edit, llvm::Any Metadata) {
-  edit.Metadata = std::move(Metadata);
-  return edit;
+// FIXME: If `Metadata` returns an `llvm::Expected` the `AnyGenerator` will
+// construct an `llvm::Expected` where no error is present but the
+// `llvm::Any` holds the error. This is unlikely but potentially surprising.
+// Perhaps the `llvm::Expected` should be unwrapped, or perhaps this should be a
+// compile-time error. No solution here is perfect.
+//
+// Note: This function template accepts any type callable with a MatchResult
+// rather than a `std::function` because the return-type needs to be deduced. If
+// it accepted a `std::function`, lambdas or other callable
+// types would not be able to deduce `R`, and users would be forced to specify
+// explicitly the type they intended to return by wrapping the lambda at the
+// call-site.
+template 
+inline ASTEdit withMetadata(ASTEdit Edit, Callable Metadata) {
+  Edit.Metadata =
+  [Gen = std::move(Metadata)](
+  const ast_matchers::MatchFinder::MatchResult &R) -> llvm::Any {
+return Gen(R);
+  };
+
+  return Edit;
 }
 
 /// The following three functions are a low-level part of the RewriteRule
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
ht

[clang] bd994b8 - Revert "[libTooling] In Clang Transformer, change `Metadata` field to deferred evalutaion"

2020-07-20 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-07-20T21:24:58Z
New Revision: bd994b81d376c7132b1155c31e99ce27a08f7ba3

URL: 
https://github.com/llvm/llvm-project/commit/bd994b81d376c7132b1155c31e99ce27a08f7ba3
DIFF: 
https://github.com/llvm/llvm-project/commit/bd994b81d376c7132b1155c31e99ce27a08f7ba3.diff

LOG: Revert "[libTooling] In Clang Transformer, change `Metadata` field to 
deferred evalutaion"

This reverts commit c0b8954ecba500e3d9609152295b74ccd7d89d62.

The commit has broken various builds. Reverting while I investigate the cause.

Added: 


Modified: 
clang/include/clang/Tooling/Transformer/RewriteRule.h
clang/lib/Tooling/Transformer/RewriteRule.cpp
clang/unittests/Tooling/TransformerTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h 
b/clang/include/clang/Tooling/Transformer/RewriteRule.h
index eb6947b54885..d9e68717d5c8 100644
--- a/clang/include/clang/Tooling/Transformer/RewriteRule.h
+++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h
@@ -47,8 +47,6 @@ using EditGenerator = MatchConsumer>;
 
 using TextGenerator = std::shared_ptr>;
 
-using AnyGenerator = MatchConsumer;
-
 // Description of a source-code edit, expressed in terms of an AST node.
 // Includes: an ID for the (bound) node, a selector for source related to the
 // node, a replacement and, optionally, an explanation for the edit.
@@ -89,11 +87,7 @@ struct ASTEdit {
   RangeSelector TargetRange;
   TextGenerator Replacement;
   TextGenerator Note;
-  // Not all transformations will want or need to attach metadata and therefore
-  // should not be required to do so.
-  AnyGenerator Metadata = [](const ast_matchers::MatchFinder::MatchResult &) {
-return llvm::Any();
-  };
+  llvm::Any Metadata;
 };
 
 /// Lifts a list of `ASTEdit`s into an `EditGenerator`.
@@ -267,27 +261,9 @@ inline ASTEdit insertAfter(RangeSelector S, TextGenerator 
Replacement) {
 /// Removes the source selected by \p S.
 ASTEdit remove(RangeSelector S);
 
-// FIXME: If `Metadata` returns an `llvm::Expected` the `AnyGenerator` will
-// construct an `llvm::Expected` where no error is present but the
-// `llvm::Any` holds the error. This is unlikely but potentially surprising.
-// Perhaps the `llvm::Expected` should be unwrapped, or perhaps this should be 
a
-// compile-time error. No solution here is perfect.
-//
-// Note: This function template accepts any type callable with a MatchResult
-// rather than a `std::function` because the return-type needs to be deduced. 
If
-// it accepted a `std::function`, lambdas or other callable
-// types would not be able to deduce `R`, and users would be forced to specify
-// explicitly the type they intended to return by wrapping the lambda at the
-// call-site.
-template 
-inline ASTEdit withMetadata(ASTEdit Edit, Callable Metadata) {
-  Edit.Metadata =
-  [Gen = std::move(Metadata)](
-  const ast_matchers::MatchFinder::MatchResult &R) -> llvm::Any {
-return Gen(R);
-  };
-
-  return Edit;
+inline ASTEdit withMetadata(ASTEdit edit, llvm::Any Metadata) {
+  edit.Metadata = std::move(Metadata);
+  return edit;
 }
 
 /// The following three functions are a low-level part of the RewriteRule

diff  --git a/clang/lib/Tooling/Transformer/RewriteRule.cpp 
b/clang/lib/Tooling/Transformer/RewriteRule.cpp
index a212a868c81d..995bec03cd66 100644
--- a/clang/lib/Tooling/Transformer/RewriteRule.cpp
+++ b/clang/lib/Tooling/Transformer/RewriteRule.cpp
@@ -44,13 +44,10 @@ translateEdits(const MatchResult &Result, ArrayRef 
ASTEdits) {
 auto Replacement = E.Replacement->eval(Result);
 if (!Replacement)
   return Replacement.takeError();
-auto Metadata = E.Metadata(Result);
-if (!Metadata)
-  return Metadata.takeError();
 transformer::Edit T;
 T.Range = *EditRange;
 T.Replacement = std::move(*Replacement);
-T.Metadata = std::move(*Metadata);
+T.Metadata = E.Metadata;
 Edits.push_back(std::move(T));
   }
   return Edits;

diff  --git a/clang/unittests/Tooling/TransformerTest.cpp 
b/clang/unittests/Tooling/TransformerTest.cpp
index 59b334b0ea5a..7d6b63293748 100644
--- a/clang/unittests/Tooling/TransformerTest.cpp
+++ b/clang/unittests/Tooling/TransformerTest.cpp
@@ -440,12 +440,6 @@ TEST_F(TransformerTest, RemoveEdit) {
 }
 
 TEST_F(TransformerTest, WithMetadata) {
-  auto makeMetadata = [](const MatchFinder::MatchResult &R) -> llvm::Any {
-int N =
-R.Nodes.getNodeAs("int")->getValue().getLimitedValue();
-return N;
-  };
-
   std::string Input = R"cc(
 int f() {
   int x = 5;
@@ -454,11 +448,8 @@ TEST_F(TransformerTest, WithMetadata) {
   )cc";
 
   Transformer T(
-  makeRule(
-  declStmt(containsDeclaration(0, varDecl(hasInitializer(
-  integerLiteral().bind("int")
-  .bind("decl"),
-  withMetadata(remove(statement(std::string("decl")))

[clang] e5b3202 - [libTooling] In Clang Transformer, change `Metadata` field to deferred evaluation.

2020-07-21 Thread Yitzhak Mandelbaum via cfe-commits

Author: Andy Soffer
Date: 2020-07-21T18:05:49Z
New Revision: e5b3202b6f9484590c9e70b8bb82d2778d1ca4fe

URL: 
https://github.com/llvm/llvm-project/commit/e5b3202b6f9484590c9e70b8bb82d2778d1ca4fe
DIFF: 
https://github.com/llvm/llvm-project/commit/e5b3202b6f9484590c9e70b8bb82d2778d1ca4fe.diff

LOG: [libTooling] In Clang Transformer, change `Metadata` field to deferred 
evaluation.

`Metadata` is being changed from an `llvm::Any` to a `MatchConsumer`
so that it's evaluation can be be dependent on on `MatchResult`s passed in.

Reviewed By: ymandel, gribozavr2

Differential Revision: https://reviews.llvm.org/D83820

Added: 


Modified: 
clang/include/clang/Tooling/Transformer/RewriteRule.h
clang/lib/Tooling/Transformer/RewriteRule.cpp
clang/unittests/Tooling/TransformerTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h 
b/clang/include/clang/Tooling/Transformer/RewriteRule.h
index d9e68717d5c8..1be572736460 100644
--- a/clang/include/clang/Tooling/Transformer/RewriteRule.h
+++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h
@@ -47,6 +47,8 @@ using EditGenerator = MatchConsumer>;
 
 using TextGenerator = std::shared_ptr>;
 
+using AnyGenerator = MatchConsumer;
+
 // Description of a source-code edit, expressed in terms of an AST node.
 // Includes: an ID for the (bound) node, a selector for source related to the
 // node, a replacement and, optionally, an explanation for the edit.
@@ -87,7 +89,12 @@ struct ASTEdit {
   RangeSelector TargetRange;
   TextGenerator Replacement;
   TextGenerator Note;
-  llvm::Any Metadata;
+  // Not all transformations will want or need to attach metadata and therefore
+  // should not be requierd to do so.
+  AnyGenerator Metadata = [](const ast_matchers::MatchFinder::MatchResult &)
+  -> llvm::Expected {
+return llvm::Expected(llvm::Any());
+  };
 };
 
 /// Lifts a list of `ASTEdit`s into an `EditGenerator`.
@@ -261,9 +268,27 @@ inline ASTEdit insertAfter(RangeSelector S, TextGenerator 
Replacement) {
 /// Removes the source selected by \p S.
 ASTEdit remove(RangeSelector S);
 
-inline ASTEdit withMetadata(ASTEdit edit, llvm::Any Metadata) {
-  edit.Metadata = std::move(Metadata);
-  return edit;
+// FIXME: If `Metadata` returns an `llvm::Expected` the `AnyGenerator` will
+// construct an `llvm::Expected` where no error is present but the
+// `llvm::Any` holds the error. This is unlikely but potentially surprising.
+// Perhaps the `llvm::Expected` should be unwrapped, or perhaps this should be 
a
+// compile-time error. No solution here is perfect.
+//
+// Note: This function template accepts any type callable with a MatchResult
+// rather than a `std::function` because the return-type needs to be deduced. 
If
+// it accepted a `std::function`, lambdas or other callable 
types
+// would not be able to deduce `R`, and users would be forced to specify
+// explicitly the type they intended to return by wrapping the lambda at the
+// call-site.
+template 
+inline ASTEdit withMetadata(ASTEdit Edit, Callable Metadata) {
+  Edit.Metadata =
+  [Gen = std::move(Metadata)](
+  const ast_matchers::MatchFinder::MatchResult &R) -> llvm::Any {
+return Gen(R);
+  };
+
+  return Edit;
 }
 
 /// The following three functions are a low-level part of the RewriteRule

diff  --git a/clang/lib/Tooling/Transformer/RewriteRule.cpp 
b/clang/lib/Tooling/Transformer/RewriteRule.cpp
index 995bec03cd66..a212a868c81d 100644
--- a/clang/lib/Tooling/Transformer/RewriteRule.cpp
+++ b/clang/lib/Tooling/Transformer/RewriteRule.cpp
@@ -44,10 +44,13 @@ translateEdits(const MatchResult &Result, ArrayRef 
ASTEdits) {
 auto Replacement = E.Replacement->eval(Result);
 if (!Replacement)
   return Replacement.takeError();
+auto Metadata = E.Metadata(Result);
+if (!Metadata)
+  return Metadata.takeError();
 transformer::Edit T;
 T.Range = *EditRange;
 T.Replacement = std::move(*Replacement);
-T.Metadata = E.Metadata;
+T.Metadata = std::move(*Metadata);
 Edits.push_back(std::move(T));
   }
   return Edits;

diff  --git a/clang/unittests/Tooling/TransformerTest.cpp 
b/clang/unittests/Tooling/TransformerTest.cpp
index 7d6b63293748..59b334b0ea5a 100644
--- a/clang/unittests/Tooling/TransformerTest.cpp
+++ b/clang/unittests/Tooling/TransformerTest.cpp
@@ -440,6 +440,12 @@ TEST_F(TransformerTest, RemoveEdit) {
 }
 
 TEST_F(TransformerTest, WithMetadata) {
+  auto makeMetadata = [](const MatchFinder::MatchResult &R) -> llvm::Any {
+int N =
+R.Nodes.getNodeAs("int")->getValue().getLimitedValue();
+return N;
+  };
+
   std::string Input = R"cc(
 int f() {
   int x = 5;
@@ -448,8 +454,11 @@ TEST_F(TransformerTest, WithMetadata) {
   )cc";
 
   Transformer T(
-  makeRule(declStmt().bind("decl"),
-   withMetadata(remove(statement(std::string("decl"))), 17)),
+  makeRule(
+  

[clang] cf42877 - [libTooling] Add assorted `EditGenerator` combinators.

2020-07-24 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-07-24T12:51:54Z
New Revision: cf428778128fed5eacee884964af53bf4a9f74f2

URL: 
https://github.com/llvm/llvm-project/commit/cf428778128fed5eacee884964af53bf4a9f74f2
DIFF: 
https://github.com/llvm/llvm-project/commit/cf428778128fed5eacee884964af53bf4a9f74f2.diff

LOG: [libTooling] Add assorted `EditGenerator` combinators.

Summary:
This patch adds various combinators that help in constructing `EditGenerator`s:
   * `noEdits`
   * `ifBound`, specialized to `ASTEdit`
   * `flatten` and `flattenVector` which allow for easy construction from a set
 of sub edits.
   * `shrinkTo`, which generates edits to shrink a given range to another that
 it encloses.

Reviewers: asoffer, gribozavr2

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D84310

Added: 


Modified: 
clang/include/clang/Tooling/Transformer/MatchConsumer.h
clang/include/clang/Tooling/Transformer/RewriteRule.h
clang/lib/Tooling/Transformer/RewriteRule.cpp
clang/unittests/Tooling/TransformerTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/MatchConsumer.h 
b/clang/include/clang/Tooling/Transformer/MatchConsumer.h
index f407ffce3d25..cb0a5f684b7d 100644
--- a/clang/include/clang/Tooling/Transformer/MatchConsumer.h
+++ b/clang/include/clang/Tooling/Transformer/MatchConsumer.h
@@ -99,11 +99,5 @@ llvm::Expected MatchComputation::eval(
   return Output;
 }
 } // namespace transformer
-
-namespace tooling {
-// DEPRECATED: Temporary alias supporting client migration to the `transformer`
-// namespace.
-using transformer::ifBound;
-} // namespace tooling
 } // namespace clang
 #endif // LLVM_CLANG_TOOLING_TRANSFORMER_MATCH_CONSUMER_H_

diff  --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h 
b/clang/include/clang/Tooling/Transformer/RewriteRule.h
index 1be572736460..c22a2da81fe6 100644
--- a/clang/include/clang/Tooling/Transformer/RewriteRule.h
+++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h
@@ -107,9 +107,42 @@ struct ASTEdit {
 /// clients.  We recommend use of the \c AtomicChange or \c Replacements 
classes
 /// for assistance in detecting such conflicts.
 EditGenerator editList(llvm::SmallVector Edits);
-// Convenience form of `editList` for a single edit.
+/// Convenience form of `editList` for a single edit.
 EditGenerator edit(ASTEdit);
 
+/// Convenience generator for a no-op edit generator.
+inline EditGenerator noEdits() { return editList({}); }
+
+/// Convenience version of `ifBound` specialized to `ASTEdit`.
+inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit,
+ ASTEdit FalseEdit) {
+  return ifBound(std::move(ID), edit(std::move(TrueEdit)),
+ edit(std::move(FalseEdit)));
+}
+
+/// Convenience version of `ifBound` that has no "False" branch. If the node is
+/// not bound, then no edits are produced.
+inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit) {
+  return ifBound(std::move(ID), edit(std::move(TrueEdit)), noEdits());
+}
+
+/// Flattens a list of generators into a single generator whose elements are 
the
+/// concatenation of the results of the argument generators.
+EditGenerator flattenVector(SmallVector Generators);
+
+namespace detail {
+/// Convenience function to construct an \c EditGenerator. Overloaded for 
common
+/// cases so that user doesn't need to specify which factory function to
+/// use. This pattern gives benefits similar to implicit constructors, while
+/// maintaing a higher degree of explicitness.
+inline EditGenerator injectEdits(ASTEdit E) { return edit(std::move(E)); }
+inline EditGenerator injectEdits(EditGenerator G) { return G; }
+} // namespace detail
+
+template  EditGenerator flatten(Ts &&...Edits) {
+  return flattenVector({detail::injectEdits(std::forward(Edits))...});
+}
+
 /// Format of the path in an include directive -- angle brackets or quotes.
 enum class IncludeFormat {
   Quoted,
@@ -291,6 +324,14 @@ inline ASTEdit withMetadata(ASTEdit Edit, Callable 
Metadata) {
   return Edit;
 }
 
+/// Assuming that the inner range is enclosed by the outer range, creates
+/// precision edits to remove the parts of the outer range that are not 
included
+/// in the inner range.
+inline EditGenerator shrinkTo(RangeSelector outer, RangeSelector inner) {
+  return editList({remove(enclose(before(outer), before(inner))),
+   remove(enclose(after(inner), after(outer)))});
+}
+
 /// The following three functions are a low-level part of the RewriteRule
 /// API. We expose them for use in implementing the fixtures that interpret
 /// RewriteRule, like Transformer and TransfomerTidy, or for more advanced

diff  --git a/clang/lib/Tooling/Transformer/RewriteRule.cpp 
b/clang/lib/Tooling/Transformer/RewriteRule.cpp
index a212a868c81d..c145895af7ab 100644
--- a/clang/lib/Tooling/Transformer/RewriteRule.cpp
+++ b/cl

[clang] c332a98 - [libTooling] Add an `EditGenerator` that applies a rule throughout a bound node.

2020-07-24 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-07-24T14:38:17Z
New Revision: c332a984aefc6f8a6b44fd3687a5bbce3f8f035c

URL: 
https://github.com/llvm/llvm-project/commit/c332a984aefc6f8a6b44fd3687a5bbce3f8f035c
DIFF: 
https://github.com/llvm/llvm-project/commit/c332a984aefc6f8a6b44fd3687a5bbce3f8f035c.diff

LOG: [libTooling] Add an `EditGenerator` that applies a rule throughout a bound 
node.

The new combinator, `rewriteDescendants`, applies a rewrite rule to all
descendants of a specified bound node.  That rewrite rule can refer to nodes
bound by the parent, both in the matcher and in the edits.

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D84409

Added: 


Modified: 
clang/include/clang/Tooling/Transformer/RewriteRule.h
clang/lib/Tooling/Transformer/RewriteRule.cpp
clang/lib/Tooling/Transformer/Transformer.cpp
clang/unittests/Tooling/TransformerTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h 
b/clang/include/clang/Tooling/Transformer/RewriteRule.h
index c22a2da81fe6..2a26d32817dd 100644
--- a/clang/include/clang/Tooling/Transformer/RewriteRule.h
+++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h
@@ -332,6 +332,23 @@ inline EditGenerator shrinkTo(RangeSelector outer, 
RangeSelector inner) {
remove(enclose(after(inner), after(outer)))});
 }
 
+/// Applies `Rule` to all descendants of the node bound to `NodeId`. `Rule` can
+/// refer to nodes bound by the calling rule. `Rule` is not applied to the node
+/// itself.
+///
+/// For example,
+/// ```
+/// auto InlineX =
+/// makeRule(declRefExpr(to(varDecl(hasName("x", changeTo(cat("3")));
+/// makeRule(functionDecl(hasName("f"), 
hasBody(stmt().bind("body"))).bind("f"),
+///  flatten(
+///changeTo(name("f"), cat("newName")),
+///rewriteDescendants("body", InlineX)));
+/// ```
+/// Here, we find the function `f`, change its name to `newName` and change all
+/// appearances of `x` in its body to `3`.
+EditGenerator rewriteDescendants(std::string NodeId, RewriteRule Rule);
+
 /// The following three functions are a low-level part of the RewriteRule
 /// API. We expose them for use in implementing the fixtures that interpret
 /// RewriteRule, like Transformer and TransfomerTidy, or for more advanced

diff  --git a/clang/lib/Tooling/Transformer/RewriteRule.cpp 
b/clang/lib/Tooling/Transformer/RewriteRule.cpp
index c145895af7ab..ce773b59a7e7 100644
--- a/clang/lib/Tooling/Transformer/RewriteRule.cpp
+++ b/clang/lib/Tooling/Transformer/RewriteRule.cpp
@@ -7,6 +7,8 @@
 
//===--===//
 
 #include "clang/Tooling/Transformer/RewriteRule.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Stmt.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Basic/SourceLocation.h"
@@ -115,15 +117,144 @@ ASTEdit transformer::remove(RangeSelector S) {
   return change(std::move(S), std::make_shared(""));
 }
 
-RewriteRule transformer::makeRule(ast_matchers::internal::DynTypedMatcher M,
-  EditGenerator Edits,
+RewriteRule transformer::makeRule(DynTypedMatcher M, EditGenerator Edits,
   TextGenerator Explanation) {
   return RewriteRule{{RewriteRule::Case{
   std::move(M), std::move(Edits), std::move(Explanation), {;
 }
 
+namespace {
+
+/// Unconditionally binds the given node set before trying `InnerMatcher` and
+/// keeps the bound nodes on a successful match.
+template 
+class BindingsMatcher : public ast_matchers::internal::MatcherInterface {
+  ast_matchers::BoundNodes Nodes;
+  const ast_matchers::internal::Matcher InnerMatcher;
+
+public:
+  explicit BindingsMatcher(ast_matchers::BoundNodes Nodes,
+   ast_matchers::internal::Matcher InnerMatcher)
+  : Nodes(std::move(Nodes)), InnerMatcher(std::move(InnerMatcher)) {}
+
+  bool matches(
+  const T &Node, ast_matchers::internal::ASTMatchFinder *Finder,
+  ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override {
+ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
+for (const auto &N : Nodes.getMap())
+  Result.setBinding(N.first, N.second);
+if (InnerMatcher.matches(Node, Finder, &Result)) {
+  *Builder = std::move(Result);
+  return true;
+}
+return false;
+  }
+};
+
+/// Matches nodes of type T that have at least one descendant node for which 
the
+/// given inner matcher matches.  Will match for each descendant node that
+/// matches.  Based on ForEachDescendantMatcher, but takes a dynamic matcher,
+/// instead of a static one, because it is used by RewriteRule, which carries
+/// (only top-level) dynamic matchers.
+template 
+class DynamicForEachDescendantMatcher
+: public ast_matchers::intern

[clang] 04a2131 - [libTooling] Add a `between` range-selector combinator.

2020-07-28 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-07-28T17:26:12Z
New Revision: 04a21318b55756d50836f6e40f2d209f18cce417

URL: 
https://github.com/llvm/llvm-project/commit/04a21318b55756d50836f6e40f2d209f18cce417
DIFF: 
https://github.com/llvm/llvm-project/commit/04a21318b55756d50836f6e40f2d209f18cce417.diff

LOG: [libTooling] Add a `between` range-selector combinator.

Adds the `between` combinator and registers it with the parser. As a driveby, 
updates some deprecated names to their current versions.

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D84315

Added: 


Modified: 
clang/include/clang/Tooling/Transformer/RangeSelector.h
clang/lib/Tooling/Transformer/Parsing.cpp
clang/unittests/Tooling/RangeSelectorTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/RangeSelector.h 
b/clang/include/clang/Tooling/Transformer/RangeSelector.h
index 2807037bc208..e070c0e7e2e6 100644
--- a/clang/include/clang/Tooling/Transformer/RangeSelector.h
+++ b/clang/include/clang/Tooling/Transformer/RangeSelector.h
@@ -56,6 +56,11 @@ RangeSelector before(RangeSelector Selector);
 /// * the TokenRange [B,E'] where the token at E' spans the range [E',E).
 RangeSelector after(RangeSelector Selector);
 
+/// Selects the range between `R1` and `R2.
+inline RangeSelector between(RangeSelector R1, RangeSelector R2) {
+  return enclose(after(std::move(R1)), before(std::move(R2)));
+}
+
 /// Selects a node, including trailing semicolon (for non-expression
 /// statements). \p ID is the node's binding in the match result.
 RangeSelector node(std::string ID);

diff  --git a/clang/lib/Tooling/Transformer/Parsing.cpp 
b/clang/lib/Tooling/Transformer/Parsing.cpp
index 1579115b9313..fb5fd4a800bb 100644
--- a/clang/lib/Tooling/Transformer/Parsing.cpp
+++ b/clang/lib/Tooling/Transformer/Parsing.cpp
@@ -109,14 +109,14 @@ getUnaryRangeSelectors() {
 static const llvm::StringMap> &
 getBinaryStringSelectors() {
   static const llvm::StringMap> M = {
-  {"encloseNodes", range}};
+  {"encloseNodes", encloseNodes}};
   return M;
 }
 
 static const llvm::StringMap> &
 getBinaryRangeSelectors() {
   static const llvm::StringMap>
-  M = {{"enclose", range}};
+  M = {{"enclose", enclose}, {"between", between}};
   return M;
 }
 

diff  --git a/clang/unittests/Tooling/RangeSelectorTest.cpp 
b/clang/unittests/Tooling/RangeSelectorTest.cpp
index e2d7723eab11..64ddee7894eb 100644
--- a/clang/unittests/Tooling/RangeSelectorTest.cpp
+++ b/clang/unittests/Tooling/RangeSelectorTest.cpp
@@ -193,8 +193,33 @@ TEST(RangeSelectorTest, AfterOp) {
HasValue(EqualsCharSourceRange(ExpectedAfter)));
 }
 
+TEST(RangeSelectorTest, BetweenOp) {
+  StringRef Code = R"cc(
+int f(int x, int y, int z) { return 3; }
+int g() { return f(3, /* comment */ 7 /* comment */, 9); }
+  )cc";
+  auto Matcher = callExpr(hasArgument(0, expr().bind("a0")),
+  hasArgument(1, expr().bind("a1")));
+  RangeSelector R = between(node("a0"), node("a1"));
+  TestMatch Match = matchCode(Code, Matcher);
+  EXPECT_THAT_EXPECTED(select(R, Match), HasValue(", /* comment */ "));
+}
+
+TEST(RangeSelectorTest, BetweenOpParsed) {
+  StringRef Code = R"cc(
+int f(int x, int y, int z) { return 3; }
+int g() { return f(3, /* comment */ 7 /* comment */, 9); }
+  )cc";
+  auto Matcher = callExpr(hasArgument(0, expr().bind("a0")),
+  hasArgument(1, expr().bind("a1")));
+  auto R = parseRangeSelector(R"rs(between(node("a0"), node("a1")))rs");
+  ASSERT_THAT_EXPECTED(R, llvm::Succeeded());
+  TestMatch Match = matchCode(Code, Matcher);
+  EXPECT_THAT_EXPECTED(select(*R, Match), HasValue(", /* comment */ "));
+}
+
 // Node-id specific version.
-TEST(RangeSelectorTest, RangeOpNodes) {
+TEST(RangeSelectorTest, EncloseOpNodes) {
   StringRef Code = R"cc(
 int f(int x, int y, int z) { return 3; }
 int g() { return f(/* comment */ 3, 7 /* comment */, 9); }
@@ -206,7 +231,7 @@ TEST(RangeSelectorTest, RangeOpNodes) {
   EXPECT_THAT_EXPECTED(select(R, Match), HasValue("3, 7"));
 }
 
-TEST(RangeSelectorTest, RangeOpGeneral) {
+TEST(RangeSelectorTest, EncloseOpGeneral) {
   StringRef Code = R"cc(
 int f(int x, int y, int z) { return 3; }
 int g() { return f(/* comment */ 3, 7 /* comment */, 9); }
@@ -218,7 +243,7 @@ TEST(RangeSelectorTest, RangeOpGeneral) {
   EXPECT_THAT_EXPECTED(select(R, Match), HasValue("3, 7"));
 }
 
-TEST(RangeSelectorTest, RangeOpNodesParsed) {
+TEST(RangeSelectorTest, EncloseOpNodesParsed) {
   StringRef Code = R"cc(
 int f(int x, int y, int z) { return 3; }
 int g() { return f(/* comment */ 3, 7 /* comment */, 9); }
@@ -231,7 +256,7 @@ TEST(RangeSelectorTest, RangeOpNodesParsed) {
   EXPECT_THAT_EXPECTED(select(*R, Match), HasValue("3, 7"));
 }
 
-TEST(RangeSelectorTest, RangeOpGeneralParsed) {
+TEST(RangeSelectorTest, EncloseOpGeneral

[clang] 5e5d366 - [libTooling] Simplify the representation of Transformer's RewriteRules.

2020-04-08 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-04-08T08:45:41-04:00
New Revision: 5e5d36671833e186e847e74bb5ed0c559625b906

URL: 
https://github.com/llvm/llvm-project/commit/5e5d36671833e186e847e74bb5ed0c559625b906
DIFF: 
https://github.com/llvm/llvm-project/commit/5e5d36671833e186e847e74bb5ed0c559625b906.diff

LOG: [libTooling] Simplify the representation of Transformer's RewriteRules.

Summary:
This revision simplifies the representation of edits in rewrite rules. The
simplified form is more general, allowing the user more flexibility in building
custom edit specifications.

The changes extend the API, without changing the signature of existing
functions. So this only risks breaking users that directly accessed the
`RewriteRule` struct.

Reviewers: gribozavr2

Subscribers: jfb, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77419

Added: 


Modified: 
clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
clang/include/clang/Tooling/Transformer/RewriteRule.h
clang/lib/Tooling/Transformer/RewriteRule.cpp
clang/lib/Tooling/Transformer/Transformer.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp 
b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
index 515997b14231..821c6290fe01 100644
--- a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
@@ -73,16 +73,15 @@ void TransformerClangTidyCheck::check(
 
   assert(Rule && "check() should not fire if Rule is None");
   RewriteRule::Case Case = transformer::detail::findSelectedCase(Result, 
*Rule);
-  Expected>
-  Transformations = transformer::detail::translateEdits(Result, 
Case.Edits);
-  if (!Transformations) {
-llvm::errs() << "Rewrite failed: "
- << llvm::toString(Transformations.takeError()) << "\n";
+  Expected> Edits = Case.Edits(Result);
+  if (!Edits) {
+llvm::errs() << "Rewrite failed: " << llvm::toString(Edits.takeError())
+ << "\n";
 return;
   }
 
   // No rewrite applied, but no error encountered either.
-  if (Transformations->empty())
+  if (Edits->empty())
 return;
 
   Expected Explanation = Case.Explanation->eval(Result);
@@ -93,9 +92,8 @@ void TransformerClangTidyCheck::check(
   }
 
   // Associate the diagnostic with the location of the first change.
-  DiagnosticBuilder Diag =
-  diag((*Transformations)[0].Range.getBegin(), *Explanation);
-  for (const auto &T : *Transformations)
+  DiagnosticBuilder Diag = diag((*Edits)[0].Range.getBegin(), *Explanation);
+  for (const auto &T : *Edits)
 Diag << FixItHint::CreateReplacement(T.Range, T.Replacement);
 
   for (const auto &I : Case.AddedIncludes) {

diff  --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h 
b/clang/include/clang/Tooling/Transformer/RewriteRule.h
index 4fca3bc9e2e8..4a5e5556cdff 100644
--- a/clang/include/clang/Tooling/Transformer/RewriteRule.h
+++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h
@@ -30,6 +30,19 @@
 
 namespace clang {
 namespace transformer {
+/// A concrete description of a source edit, represented by a character range 
in
+/// the source to be replaced and a corresponding replacement string.
+struct Edit {
+  CharSourceRange Range;
+  std::string Replacement;
+};
+
+/// Maps a match result to a list of concrete edits (with possible
+/// failure). This type is a building block of rewrite rules, but users will
+/// generally work in terms of `ASTEdit`s (below) rather than directly in terms
+/// of `EditGenerator`.
+using EditGenerator = MatchConsumer>;
+
 using TextGenerator = std::shared_ptr>;
 
 // Description of a source-code edit, expressed in terms of an AST node.
@@ -74,6 +87,19 @@ struct ASTEdit {
   TextGenerator Note;
 };
 
+/// Lifts a list of `ASTEdit`s into an `EditGenerator`.
+///
+/// The `EditGenerator` will return an empty vector if any of the edits apply 
to
+/// portions of the source that are ineligible for rewriting (certain
+/// interactions with macros, for example) and it will fail if any invariants
+/// are violated relating to bound nodes in the match.  However, it does not
+/// fail in the case of conflicting edits -- conflict handling is left to
+/// clients.  We recommend use of the \c AtomicChange or \c Replacements 
classes
+/// for assistance in detecting such conflicts.
+EditGenerator editList(llvm::SmallVector Edits);
+// Convenience form of `editList` for a single edit.
+EditGenerator edit(ASTEdit);
+
 /// Format of the path in an include directive -- angle brackets or quotes.
 enum class IncludeFormat {
   Quoted,
@@ -106,7 +132,7 @@ enum class IncludeFormat {
 struct RewriteRule {
   struct Case {
 ast_matchers::internal::DynTypedMatcher Matcher;
-SmallVector Edits;
+EditGenerator Edits;
 TextGenerator Explanation;
 // Include paths to add to the

[clang] ecfa0b2 - [libTooling] Fix `maybeExtendRange` to support `CharRange`s.

2020-07-01 Thread Yitzhak Mandelbaum via cfe-commits

Author: Gabriel Matute
Date: 2020-07-01T20:40:48Z
New Revision: ecfa0b24189abf4bb172a8860048af05fa17daee

URL: 
https://github.com/llvm/llvm-project/commit/ecfa0b24189abf4bb172a8860048af05fa17daee
DIFF: 
https://github.com/llvm/llvm-project/commit/ecfa0b24189abf4bb172a8860048af05fa17daee.diff

LOG: [libTooling] Fix `maybeExtendRange` to support `CharRange`s.

Currently, `maybeExtendRange` takes a `CharSourceRange`, but only works
correctly for the `TokenRange` case. This change adds proper support for the
`CharRange` case.

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D82901

Added: 


Modified: 
clang/lib/Tooling/Transformer/SourceCode.cpp
clang/unittests/Tooling/SourceCodeTest.cpp

Removed: 




diff  --git a/clang/lib/Tooling/Transformer/SourceCode.cpp 
b/clang/lib/Tooling/Transformer/SourceCode.cpp
index a29d2e796d94..26b204851f05 100644
--- a/clang/lib/Tooling/Transformer/SourceCode.cpp
+++ b/clang/lib/Tooling/Transformer/SourceCode.cpp
@@ -37,11 +37,17 @@ StringRef clang::tooling::getText(CharSourceRange Range,
 CharSourceRange clang::tooling::maybeExtendRange(CharSourceRange Range,
  tok::TokenKind Next,
  ASTContext &Context) {
-  Optional Tok = Lexer::findNextToken(
-  Range.getEnd(), Context.getSourceManager(), Context.getLangOpts());
-  if (!Tok || !Tok->is(Next))
+  CharSourceRange R = Lexer::getAsCharRange(Range, Context.getSourceManager(),
+Context.getLangOpts());
+  if (R.isInvalid())
 return Range;
-  return CharSourceRange::getTokenRange(Range.getBegin(), Tok->getLocation());
+  Token Tok;
+  bool Err =
+  Lexer::getRawToken(R.getEnd(), Tok, Context.getSourceManager(),
+ Context.getLangOpts(), /*IgnoreWhiteSpace=*/true);
+  if (Err || !Tok.is(Next))
+return Range;
+  return CharSourceRange::getTokenRange(Range.getBegin(), Tok.getLocation());
 }
 
 llvm::Error clang::tooling::validateEditRange(const CharSourceRange &Range,

diff  --git a/clang/unittests/Tooling/SourceCodeTest.cpp 
b/clang/unittests/Tooling/SourceCodeTest.cpp
index aeb0ca36582b..eb652cf03064 100644
--- a/clang/unittests/Tooling/SourceCodeTest.cpp
+++ b/clang/unittests/Tooling/SourceCodeTest.cpp
@@ -9,6 +9,8 @@
 #include "clang/Tooling/Transformer/SourceCode.h"
 #include "TestVisitor.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
 #include "llvm/Testing/Support/Annotations.h"
 #include "llvm/Testing/Support/Error.h"
 #include "llvm/Testing/Support/SupportHelpers.h"
@@ -21,9 +23,11 @@ using llvm::Failed;
 using llvm::Succeeded;
 using llvm::ValueIs;
 using tooling::getAssociatedRange;
+using tooling::getExtendedRange;
 using tooling::getExtendedText;
 using tooling::getRangeForEdit;
 using tooling::getText;
+using tooling::maybeExtendRange;
 using tooling::validateEditRange;
 
 namespace {
@@ -52,7 +56,7 @@ MATCHER_P(EqualsRange, R, "") {
  arg.getBegin() == R.getBegin() && arg.getEnd() == R.getEnd();
 }
 
-MATCHER_P2(EqualsAnnotatedRange, SM, R, "") {
+MATCHER_P2(EqualsAnnotatedRange, Context, R, "") {
   if (arg.getBegin().isMacroID()) {
 *result_listener << "which starts in a macro";
 return false;
@@ -62,15 +66,13 @@ MATCHER_P2(EqualsAnnotatedRange, SM, R, "") {
 return false;
   }
 
-  unsigned Begin = SM->getFileOffset(arg.getBegin());
-  unsigned End = SM->getFileOffset(arg.getEnd());
+  CharSourceRange Range = Lexer::getAsCharRange(
+  arg, Context->getSourceManager(), Context->getLangOpts());
+  unsigned Begin = Context->getSourceManager().getFileOffset(Range.getBegin());
+  unsigned End = Context->getSourceManager().getFileOffset(Range.getEnd());
 
-  *result_listener << "which is [" << Begin << ",";
-  if (arg.isTokenRange()) {
-*result_listener << End << "]";
-return Begin == R.Begin && End + 1 == R.End;
-  }
-  *result_listener << End << ")";
+  *result_listener << "which is a " << (arg.isTokenRange() ? "Token" : "Char")
+   << " range [" << Begin << "," << End << ")";
   return Begin == R.Begin && End == R.End;
 }
 
@@ -84,11 +86,13 @@ static ::testing::Matcher AsRange(const 
SourceManager &SM,
 // Base class for visitors that expect a single match corresponding to a
 // specific annotated range.
 template  class AnnotatedCodeVisitor : public TestVisitor {
-  llvm::Annotations Code;
+protected:
   int MatchCount = 0;
+  llvm::Annotations Code;
 
 public:
   AnnotatedCodeVisitor() : Code("$r[[]]") {}
+  // Helper for tests of `getAssociatedRange`.
   bool VisitDeclHelper(Decl *Decl) {
 // Only consider explicit declarations.
 if (Decl->isImplicit())
@@ -96,8 +100,7 @@ template  class AnnotatedCodeVisitor : public 
TestVisitor {
 
 ++MatchCount;
 EXPECT_THAT(getAssociatedRange(*Decl, *this-

[clang] 9ca50e8 - [libTooling] Add parser for string representation of `RangeSelector`.

2020-06-18 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-06-19T01:11:29Z
New Revision: 9ca50e887db7f903c04a90593d2beed8a96794f1

URL: 
https://github.com/llvm/llvm-project/commit/9ca50e887db7f903c04a90593d2beed8a96794f1
DIFF: 
https://github.com/llvm/llvm-project/commit/9ca50e887db7f903c04a90593d2beed8a96794f1.diff

LOG: [libTooling] Add parser for string representation of `RangeSelector`.

This patch adds a parser for a `RangeSelector` written as a string. The format
is closely based on the way one would right the selector in C++. This should
enable use of `RangeSelector`s from tools like clang-query and web UIs.

Added: 
clang/include/clang/Tooling/Transformer/Parsing.h
clang/lib/Tooling/Transformer/Parsing.cpp

Modified: 
clang/lib/Tooling/Transformer/CMakeLists.txt
clang/unittests/Tooling/RangeSelectorTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/Parsing.h 
b/clang/include/clang/Tooling/Transformer/Parsing.h
new file mode 100644
index ..8e51f595cd5b
--- /dev/null
+++ b/clang/include/clang/Tooling/Transformer/Parsing.h
@@ -0,0 +1,41 @@
+//===--- Parsing.h - Parsing library for Transformer *- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+///  \file
+///  Defines parsing functions for Transformer types.
+///  FIXME: Currently, only supports `RangeSelectors` but parsers for other
+///  Transformer types are under development.
+///
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_PARSING_H_
+#define LLVM_CLANG_TOOLING_REFACTOR_PARSING_H_
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+
+namespace clang {
+namespace transformer {
+
+/// Parses a string representation of a \c RangeSelector. The grammar of these
+/// strings is closely based on the (sub)grammar of \c RangeSelectors as they'd
+/// appear in C++ code. However, this language constrains the set of 
permissible
+/// strings (for node ids) -- it does not support escapes in the
+/// string. Additionally, the \c charRange combinator is not supported, because
+/// there is no representation of values of type \c CharSourceRange in this
+/// (little) language.
+llvm::Expected parseRangeSelector(llvm::StringRef Input);
+
+} // namespace transformer
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_PARSING_H_

diff  --git a/clang/lib/Tooling/Transformer/CMakeLists.txt 
b/clang/lib/Tooling/Transformer/CMakeLists.txt
index 281af1007a65..150b71b1ffcd 100644
--- a/clang/lib/Tooling/Transformer/CMakeLists.txt
+++ b/clang/lib/Tooling/Transformer/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
 )
 
 add_clang_library(clangTransformer
+  Parsing.cpp
   RangeSelector.cpp
   RewriteRule.cpp
   SourceCode.cpp

diff  --git a/clang/lib/Tooling/Transformer/Parsing.cpp 
b/clang/lib/Tooling/Transformer/Parsing.cpp
new file mode 100644
index ..1579115b9313
--- /dev/null
+++ b/clang/lib/Tooling/Transformer/Parsing.cpp
@@ -0,0 +1,279 @@
+//===--- Parsing.cpp - Parsing function implementations -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/Tooling/Transformer/Parsing.h"
+#include "clang/AST/Expr.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "clang/Tooling/Transformer/SourceCode.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+#include 
+#include 
+#include 
+
+using namespace clang;
+using namespace transformer;
+
+// FIXME: This implementation is entirely separate from that of the AST
+// matchers. Given the similarity of the languages and uses of the two parsers,
+// the two should share a common parsing infrastructure, as should other
+// Transformer types. We intend to unify this implementation soon to share as
+// much as possible with the AST Matchers parsing.
+
+namespace {
+using llvm::Error;
+using llvm::Expected;
+
+template  using RangeSelectorOp = RangeSelector (*)(Ts...);
+
+struct ParseState {
+  // The remaining input to be processed.
+  St

[clang] d81d69f - [libTooling] Change Transformer's `cat` to handle some cases of text in macros.

2020-06-19 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-06-19T18:48:54Z
New Revision: d81d69f1c0c161e093531cf1ac9c1fa280ab5bf1

URL: 
https://github.com/llvm/llvm-project/commit/d81d69f1c0c161e093531cf1ac9c1fa280ab5bf1
DIFF: 
https://github.com/llvm/llvm-project/commit/d81d69f1c0c161e093531cf1ac9c1fa280ab5bf1.diff

LOG: [libTooling] Change Transformer's `cat` to handle some cases of text in 
macros.

Summary:
Currently, `cat` validates range selections before extracting the corresponding
source text. However, this means that any range inside a macro is rejected as an
error. This patch changes the implementation to first try to map the range to
something reasonable. This makes the behavior consistent with handling of ranges
used for selecting portions of the source to edit.

Also updates a clang-tidy lit-test for one of the checks which was affected by
this change.

Reviewers: gribozavr2, tdl-g

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82126

Added: 


Modified: 

clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp
clang/lib/Tooling/Transformer/Stencil.cpp
clang/unittests/Tooling/StencilTest.cpp

Removed: 




diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp
index 871c830b81cf..9d4b03aa22f2 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp
@@ -239,16 +239,12 @@ void no_char_param_tests() {
   asv.find('c') == absl::string_view::npos;
 }
 
-#define COMPARE_MACRO(x, y) ((x) == (y))
-#define FIND_MACRO(x, y) ((x).find(y))
-#define FIND_COMPARE_MACRO(x, y, z) ((x).find(y) == (z))
-
-// Confirms that it does not match when a macro is involved.
-void no_macros() {
-  std::string s;
-  COMPARE_MACRO(s.find("a"), std::string::npos);
-  FIND_MACRO(s, "a") == std::string::npos;
-  FIND_COMPARE_MACRO(s, "a", std::string::npos);
+#define FOO(a, b, c, d) ((a).find(b) == std::string::npos ? (c) : (d))
+
+// Confirms that it does not match when a macro would be "torn" by the fix.
+void no_tearing_macros() {
+  std::string h = "helo";
+  FOO(h, "x", 5, 6);
 }
 
 // Confirms that it does not match when the pos parameter is non-zero.

diff  --git a/clang/lib/Tooling/Transformer/Stencil.cpp 
b/clang/lib/Tooling/Transformer/Stencil.cpp
index da6033efa296..31b6ad9332c8 100644
--- a/clang/lib/Tooling/Transformer/Stencil.cpp
+++ b/clang/lib/Tooling/Transformer/Stencil.cpp
@@ -12,6 +12,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Tooling/Transformer/SourceCode.h"
 #include "clang/Tooling/Transformer/SourceCodeBuilders.h"
@@ -226,12 +227,14 @@ Error evalData(const UnaryOperationData &Data,
 
 Error evalData(const SelectorData &Data, const MatchFinder::MatchResult &Match,
std::string *Result) {
-  auto Range = Data.Selector(Match);
-  if (!Range)
-return Range.takeError();
-  if (auto Err = tooling::validateEditRange(*Range, *Match.SourceManager))
+  auto RawRange = Data.Selector(Match);
+  if (!RawRange)
+return RawRange.takeError();
+  CharSourceRange Range = Lexer::makeFileCharRange(
+  *RawRange, *Match.SourceManager, Match.Context->getLangOpts());
+  if (auto Err = tooling::validateEditRange(Range, *Match.SourceManager))
 return Err;
-  *Result += tooling::getText(*Range, *Match.Context);
+  *Result += tooling::getText(Range, *Match.Context);
   return Error::success();
 }
 

diff  --git a/clang/unittests/Tooling/StencilTest.cpp 
b/clang/unittests/Tooling/StencilTest.cpp
index 2f0a970d8552..9408a1e62dfa 100644
--- a/clang/unittests/Tooling/StencilTest.cpp
+++ b/clang/unittests/Tooling/StencilTest.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "clang/Tooling/Transformer/Stencil.h"
+#include "clang/AST/ASTTypeTraits.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/FixIt.h"
 #include "clang/Tooling/Tooling.h"
@@ -373,6 +374,48 @@ TEST_F(StencilTest, RunOp) {
   testExpr(Id, "3;", run(SimpleFn), "Bound");
 }
 
+TEST_F(StencilTest, CatOfMacroRangeSucceeds) {
+  StringRef Snippet = R"cpp(
+#define MACRO 3.77
+  double foo(double d);
+  foo(MACRO);)cpp";
+
+  auto StmtMatch =
+  matchStmt(Snippet, callExpr(callee(functionDecl(hasName("foo"))),
+  argumentCountIs(1),
+  hasArgument(0, expr().bind("arg";
+  ASSERT_TRUE(StmtMatch);
+  Stencil S = cat(node("arg"));
+  EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), HasValue("MACRO"));
+}
+
+TEST_F(StencilTest, CatOfMacroArgR

[clang] 87340a2 - [libTooling] Delete deprecated `Stencil` combinators.

2020-06-24 Thread Yitzhak Mandelbaum via cfe-commits

Author: Yitzhak Mandelbaum
Date: 2020-06-24T16:45:24Z
New Revision: 87340a2bf1d2618565b7cf606913c8968e6513fb

URL: 
https://github.com/llvm/llvm-project/commit/87340a2bf1d2618565b7cf606913c8968e6513fb
DIFF: 
https://github.com/llvm/llvm-project/commit/87340a2bf1d2618565b7cf606913c8968e6513fb.diff

LOG: [libTooling] Delete deprecated `Stencil` combinators.

Summary: Deletes `text()` and `selection()` combinators, since they have been 
deprecated for months.

Reviewers: tdl-g

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82225

Added: 


Modified: 
clang/include/clang/Tooling/Transformer/Stencil.h
clang/lib/Tooling/Transformer/Stencil.cpp
clang/unittests/Tooling/StencilTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Transformer/Stencil.h 
b/clang/include/clang/Tooling/Transformer/Stencil.h
index 0363b689dc5b..1b50a670f70b 100644
--- a/clang/include/clang/Tooling/Transformer/Stencil.h
+++ b/clang/include/clang/Tooling/Transformer/Stencil.h
@@ -69,14 +69,6 @@ template  Stencil cat(Ts &&... Parts) {
 // Functions for conveniently building stencils.
 //
 
-/// DEPRECATED: Use `cat` instead.
-/// \returns exactly the text provided.
-Stencil text(llvm::StringRef Text);
-
-/// DEPRECATED: Use `cat` instead.
-/// \returns the source corresponding to the selected range.
-Stencil selection(RangeSelector Selector);
-
 /// Generates the source of the expression bound to \p Id, wrapping it in
 /// parentheses if it may parse 
diff erently depending on context. For example, a
 /// binary operation is always wrapped, while a variable reference is never
@@ -112,7 +104,7 @@ Stencil maybeAddressOf(llvm::StringRef ExprId);
 /// Additionally, `e` is wrapped in parentheses, if needed.
 Stencil access(llvm::StringRef BaseId, Stencil Member);
 inline Stencil access(llvm::StringRef BaseId, llvm::StringRef Member) {
-  return access(BaseId, text(Member));
+  return access(BaseId, detail::makeStencil(Member));
 }
 
 /// Chooses between the two stencil parts, based on whether \p ID is bound in
@@ -123,7 +115,8 @@ Stencil ifBound(llvm::StringRef Id, Stencil TrueStencil, 
Stencil FalseStencil);
 /// match.
 inline Stencil ifBound(llvm::StringRef Id, llvm::StringRef TrueText,
llvm::StringRef FalseText) {
-  return ifBound(Id, text(TrueText), text(FalseText));
+  return ifBound(Id, detail::makeStencil(TrueText),
+ detail::makeStencil(FalseText));
 }
 
 /// Wraps a \c MatchConsumer in a \c Stencil, so that it can be used in a \c

diff  --git a/clang/lib/Tooling/Transformer/Stencil.cpp 
b/clang/lib/Tooling/Transformer/Stencil.cpp
index 31b6ad9332c8..619467383e70 100644
--- a/clang/lib/Tooling/Transformer/Stencil.cpp
+++ b/clang/lib/Tooling/Transformer/Stencil.cpp
@@ -298,17 +298,11 @@ template  class StencilImpl : public 
StencilInterface {
 };
 } // namespace
 
-Stencil transformer::detail::makeStencil(StringRef Text) { return text(Text); }
-
-Stencil transformer::detail::makeStencil(RangeSelector Selector) {
-  return selection(std::move(Selector));
-}
-
-Stencil transformer::text(StringRef Text) {
+Stencil transformer::detail::makeStencil(StringRef Text) {
   return std::make_shared>(std::string(Text));
 }
 
-Stencil transformer::selection(RangeSelector Selector) {
+Stencil transformer::detail::makeStencil(RangeSelector Selector) {
   return std::make_shared>(std::move(Selector));
 }
 

diff  --git a/clang/unittests/Tooling/StencilTest.cpp 
b/clang/unittests/Tooling/StencilTest.cpp
index 9408a1e62dfa..648c583273a2 100644
--- a/clang/unittests/Tooling/StencilTest.cpp
+++ b/clang/unittests/Tooling/StencilTest.cpp
@@ -180,12 +180,12 @@ TEST_F(StencilTest, SelectionOp) {
 
 TEST_F(StencilTest, IfBoundOpBound) {
   StringRef Id = "id";
-  testExpr(Id, "3;", ifBound(Id, text("5"), text("7")), "5");
+  testExpr(Id, "3;", ifBound(Id, cat("5"), cat("7")), "5");
 }
 
 TEST_F(StencilTest, IfBoundOpUnbound) {
   StringRef Id = "id";
-  testExpr(Id, "3;", ifBound("other", text("5"), text("7")), "7");
+  testExpr(Id, "3;", ifBound("other", cat("5"), cat("7")), "7");
 }
 
 TEST_F(StencilTest, ExpressionOpNoParens) {
@@ -293,7 +293,7 @@ TEST_F(StencilTest, AccessOpValueExplicitText) {
 x;
   )cc";
   StringRef Id = "id";
-  testExpr(Id, Snippet, access(Id, text("field")), "x.field");
+  testExpr(Id, Snippet, access(Id, cat("field")), "x.field");
 }
 
 TEST_F(StencilTest, AccessOpValueAddress) {
@@ -479,7 +479,7 @@ TEST(StencilToStringTest, AccessOpText) {
 }
 
 TEST(StencilToStringTest, AccessOpSelector) {
-  auto S = access("Id", selection(name("otherId")));
+  auto S = access("Id", cat(name("otherId")));
   StringRef Expected = R"repr(access("Id", selection(...)))repr";
   EXPECT_EQ(S->toString(), Expected);
 }
@@ -491,7 +491,7 @@ TEST(StencilToStringTest, AccessOpStencil) {
 }
 
 TEST(StencilToStringTest, IfBoundOp) {
-  auto S = ifBound("Id", tex

Re: [PATCH] D82225: [libTooling] Delete deprecated `Stencil` combinators.

2020-06-25 Thread Yitzhak Mandelbaum via cfe-commits
Thanks for alerting me. Why is it important to strip out this information?
Also, might this be something we can change on the arcanist side (to not
add to the commit message) rather than strip out on the git end?

On Wed, Jun 24, 2020 at 3:28 PM Fangrui Song via Phabricator <
revi...@reviews.llvm.org> wrote:

> MaskRay added a comment.
>
> Hi, your git commit contains extra Phabricator tags. You can drop
> `Reviewers:` `Subscribers:` `Tags:` and the text `Summary:` from the git
> commit with the following script:
>
>   arcfilter () {
>   arc amend
>   git log -1 --pretty=%B | awk '/Reviewers:|Subscribers:/{p=1}
> /Reviewed By:|Differential Revision:/{p=0} !p && !/^Summary:$/
> {sub(/^Summary: /,"");print}' | git commit --amend --date=now -F -
>   }
>
> `Reviewed By: ` is considered important by some people. Please keep the
> tag. (I have updated my script to use `--date=now` (setting author date to
> committer date))
>
> `https://reviews.llvm.org/D80978` 
> contains a git pre-push hook to automate this.
>
>
> Repository:
>   rG LLVM Github Monorepo
>
> CHANGES SINCE LAST ACTION
>   https://reviews.llvm.org/D82225/new/
>
> https://reviews.llvm.org/D82225
>
>
>
>


smime.p7s
Description: S/MIME Cryptographic Signature
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   6   7   >