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

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 24 18:45:32 PST 2015


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151124/4e5e7f8f/attachment-0001.html>


More information about the cfe-commits mailing list