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 23:45:04 PST 2015


Unfortunately, the bot still seems to be unhappy:
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-autoconf/builds/12246/steps/build%20fresh%20clang/logs/stdio

On Tue, Nov 24, 2015 at 6:45 PM, Richard Smith <richard at metafoo.co.uk>
wrote:

> Hah, looks like a rejects-valid, but it found a real bug, so *shrug*. =)
> Hopefully fixed in r254053.
>
>
> On Tue, Nov 24, 2015 at 5:14 PM, Alexey Samsonov <vonosmas at gmail.com>
> wrote:
>
>> 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
>>
>
>


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


More information about the cfe-commits mailing list