r254041 - Teach RAV to pass its DataRecursionQueue to derived classes if they ask for it,

Alexey Samsonov via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 24 17:14:35 PST 2015


Hm, looks like we can't compile Clang itself after this change (with GCC):

http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-autoconf/builds/12237

On Tue, Nov 24, 2015 at 3:50 PM, Richard Smith via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: rsmith
> Date: Tue Nov 24 17:50:47 2015
> New Revision: 254041
>
> URL: http://llvm.org/viewvc/llvm-project?rev=254041&view=rev
> Log:
> Teach RAV to pass its DataRecursionQueue to derived classes if they ask
> for it,
> to allow them to explicitly opt into data recursion despite having
> overridden
> Traverse*Stmt or Traverse*Expr. Use this to reintroduce data recursion to
> the
> one place that lost it when DataRecursiveASTVisitor was removed.
>
> Modified:
>     cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>     cfe/trunk/tools/libclang/IndexBody.cpp
>
> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=254041&r1=254040&r2=254041&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Nov 24 17:50:47
> 2015
> @@ -14,6 +14,8 @@
>  #ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
>  #define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
>
> +#include <type_traits>
> +
>  #include "clang/AST/Attr.h"
>  #include "clang/AST/Decl.h"
>  #include "clang/AST/DeclCXX.h"
> @@ -132,13 +134,13 @@ namespace clang {
>  /// instantiations will be visited at the same time as the pattern
>  /// from which they were produced.
>  template <typename Derived> class RecursiveASTVisitor {
> +public:
>    /// A queue used for performing data recursion over statements.
>    /// Parameters involving this type are used to implement data
>    /// recursion over Stmts and Exprs within this class, and should
> -  /// not be explicitly specified by derived classes.
> +  /// typically not be explicitly specified by derived classes.
>    typedef SmallVectorImpl<Stmt *> DataRecursionQueue;
>
> -public:
>    /// \brief Return a reference to the derived class.
>    Derived &getDerived() { return *static_cast<Derived *>(this); }
>
> @@ -274,24 +276,32 @@ public:
>  // ---- Methods on Stmts ----
>
>  private:
> -  template<typename T, T X, typename U, U Y>
> -  struct is_same_member_pointer : std::false_type {};
> -  template<typename T, T X>
> -  struct is_same_member_pointer<T, X, T, X> : std::true_type {};
> -
> -  // Traverse the given statement. If the traverse function was not
> overridden,
> -  // pass on the data recursion queue information.
> +  // Determine if the specified derived-class member M can be passed a
> +  // DataRecursionQueue* argument.
> +  template<typename P>
> +  std::false_type callableWithQueue(...);
> +  template<typename P, typename M>
> +  std::true_type callableWithQueue(M m, Derived *d = nullptr, P *p =
> nullptr,
> +                                   DataRecursionQueue *q = nullptr,
> +                                   decltype((d->*m)(p, q)) = false);
> +
> +  // Traverse the given statement. If the most-derived traverse function
> takes a
> +  // data recursion queue, pass it on; otherwise, discard it. Note that
> the
> +  // first branch of this conditional must compile whether or not the
> derived
> +  // class can take a queue, so if we're taking the second arm, make the
> first
> +  // arm call our function rather than the derived class version.
>  #define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE)
>       \
> -  (is_same_member_pointer<decltype(&Derived::Traverse##NAME),
>       \
> -                          &Derived::Traverse##NAME,
>       \
> -
> decltype(&RecursiveASTVisitor::Traverse##NAME),      \
> -                          &RecursiveASTVisitor::Traverse##NAME>::value
>      \
> -       ? this->Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE)
>       \
> +  (decltype(callableWithQueue<CLASS *>(&Derived::Traverse##NAME))::value
>      \
> +       ? static_cast<typename std::conditional<
>       \
> +             decltype(
>      \
> +                 callableWithQueue<CLASS
> *>(&Derived::Traverse##NAME))::value, \
> +             Derived &, RecursiveASTVisitor &>::type>(*this)
>      \
> +             .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE)
>      \
>         : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))
>
> -  // Try to traverse the given statement, or enqueue it if we're
> performing data
> -  // recursion in the middle of traversing another statement. Can only be
> called
> -  // from within a DEF_TRAVERSE_STMT body or similar context.
> +// Try to traverse the given statement, or enqueue it if we're performing
> data
> +// recursion in the middle of traversing another statement. Can only be
> called
> +// from within a DEF_TRAVERSE_STMT body or similar context.
>  #define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S)
>      \
>    do {
>      \
>      if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue))
>      \
> @@ -535,14 +545,6 @@ bool RecursiveASTVisitor<Derived>::Trave
>    if (!S)
>      return true;
>
> -  // If TraverseStmt was overridden (and called the base class version),
> don't
> -  // do any data recursion; it would be observable.
> -  if (!is_same_member_pointer<decltype(&Derived::TraverseStmt),
> -                              &Derived::TraverseStmt,
> -
> decltype(&RecursiveASTVisitor::TraverseStmt),
> -                              &RecursiveASTVisitor::TraverseStmt>::value)
> -    return dataTraverseNode(S, nullptr);
> -
>    if (Queue) {
>      Queue->push_back(S);
>      return true;
>
> Modified: cfe/trunk/tools/libclang/IndexBody.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexBody.cpp?rev=254041&r1=254040&r2=254041&view=diff
>
> ==============================================================================
> --- cfe/trunk/tools/libclang/IndexBody.cpp (original)
> +++ cfe/trunk/tools/libclang/IndexBody.cpp Tue Nov 24 17:50:47 2015
> @@ -125,10 +125,11 @@ public:
>      return true;
>    }
>
> -  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
> +  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
> +                                   DataRecursionQueue *Q = nullptr) {
>      if (E->getOperatorLoc().isInvalid())
>        return true; // implicit.
> -    return base::TraverseCXXOperatorCallExpr(E);
> +    return base::TraverseCXXOperatorCallExpr(E, Q);
>    }
>
>    bool VisitDeclStmt(DeclStmt *S) {
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>



-- 
Alexey Samsonov
vonosmas at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151124/932e91a6/attachment-0001.html>


More information about the cfe-commits mailing list