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 <vonos...@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@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@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > > > > -- > Alexey Samsonov > vonos...@gmail.com >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits