<div dir="ltr">Hah, looks like a rejects-valid, but it found a real bug, so *shrug*. =) Hopefully fixed in r254053.<br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 24, 2015 at 5:14 PM, Alexey Samsonov <span dir="ltr"><<a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Hm, looks like we can't compile Clang itself after this change (with GCC):</div><div><br></div><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-autoconf/builds/12237" target="_blank">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-autoconf/builds/12237</a><br></div><div class="gmail_extra"><div><div class="h5"><br><div class="gmail_quote">On Tue, Nov 24, 2015 at 3:50 PM, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: rsmith<br>
Date: Tue Nov 24 17:50:47 2015<br>
New Revision: 254041<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=254041&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=254041&view=rev</a><br>
Log:<br>
Teach RAV to pass its DataRecursionQueue to derived classes if they ask for it,<br>
to allow them to explicitly opt into data recursion despite having overridden<br>
Traverse*Stmt or Traverse*Expr. Use this to reintroduce data recursion to the<br>
one place that lost it when DataRecursiveASTVisitor was removed.<br>
<br>
Modified:<br>
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
cfe/trunk/tools/libclang/IndexBody.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=254041&r1=254040&r2=254041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=254041&r1=254040&r2=254041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Tue Nov 24 17:50:47 2015<br>
@@ -14,6 +14,8 @@<br>
#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H<br>
#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H<br>
<br>
+#include <type_traits><br>
+<br>
#include "clang/AST/Attr.h"<br>
#include "clang/AST/Decl.h"<br>
#include "clang/AST/DeclCXX.h"<br>
@@ -132,13 +134,13 @@ namespace clang {<br>
/// instantiations will be visited at the same time as the pattern<br>
/// from which they were produced.<br>
template <typename Derived> class RecursiveASTVisitor {<br>
+public:<br>
/// A queue used for performing data recursion over statements.<br>
/// Parameters involving this type are used to implement data<br>
/// recursion over Stmts and Exprs within this class, and should<br>
- /// not be explicitly specified by derived classes.<br>
+ /// typically not be explicitly specified by derived classes.<br>
typedef SmallVectorImpl<Stmt *> DataRecursionQueue;<br>
<br>
-public:<br>
/// \brief Return a reference to the derived class.<br>
Derived &getDerived() { return *static_cast<Derived *>(this); }<br>
<br>
@@ -274,24 +276,32 @@ public:<br>
// ---- Methods on Stmts ----<br>
<br>
private:<br>
- template<typename T, T X, typename U, U Y><br>
- struct is_same_member_pointer : std::false_type {};<br>
- template<typename T, T X><br>
- struct is_same_member_pointer<T, X, T, X> : std::true_type {};<br>
-<br>
- // Traverse the given statement. If the traverse function was not overridden,<br>
- // pass on the data recursion queue information.<br>
+ // Determine if the specified derived-class member M can be passed a<br>
+ // DataRecursionQueue* argument.<br>
+ template<typename P><br>
+ std::false_type callableWithQueue(...);<br>
+ template<typename P, typename M><br>
+ std::true_type callableWithQueue(M m, Derived *d = nullptr, P *p = nullptr,<br>
+ DataRecursionQueue *q = nullptr,<br>
+ decltype((d->*m)(p, q)) = false);<br>
+<br>
+ // Traverse the given statement. If the most-derived traverse function takes a<br>
+ // data recursion queue, pass it on; otherwise, discard it. Note that the<br>
+ // first branch of this conditional must compile whether or not the derived<br>
+ // class can take a queue, so if we're taking the second arm, make the first<br>
+ // arm call our function rather than the derived class version.<br>
#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \<br>
- (is_same_member_pointer<decltype(&Derived::Traverse##NAME), \<br>
- &Derived::Traverse##NAME, \<br>
- decltype(&RecursiveASTVisitor::Traverse##NAME), \<br>
- &RecursiveASTVisitor::Traverse##NAME>::value \<br>
- ? this->Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \<br>
+ (decltype(callableWithQueue<CLASS *>(&Derived::Traverse##NAME))::value \<br>
+ ? static_cast<typename std::conditional< \<br>
+ decltype( \<br>
+ callableWithQueue<CLASS *>(&Derived::Traverse##NAME))::value, \<br>
+ Derived &, RecursiveASTVisitor &>::type>(*this) \<br>
+ .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \<br>
: getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))<br>
<br>
- // Try to traverse the given statement, or enqueue it if we're performing data<br>
- // recursion in the middle of traversing another statement. Can only be called<br>
- // from within a DEF_TRAVERSE_STMT body or similar context.<br>
+// Try to traverse the given statement, or enqueue it if we're performing data<br>
+// recursion in the middle of traversing another statement. Can only be called<br>
+// from within a DEF_TRAVERSE_STMT body or similar context.<br>
#define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S) \<br>
do { \<br>
if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \<br>
@@ -535,14 +545,6 @@ bool RecursiveASTVisitor<Derived>::Trave<br>
if (!S)<br>
return true;<br>
<br>
- // If TraverseStmt was overridden (and called the base class version), don't<br>
- // do any data recursion; it would be observable.<br>
- if (!is_same_member_pointer<decltype(&Derived::TraverseStmt),<br>
- &Derived::TraverseStmt,<br>
- decltype(&RecursiveASTVisitor::TraverseStmt),<br>
- &RecursiveASTVisitor::TraverseStmt>::value)<br>
- return dataTraverseNode(S, nullptr);<br>
-<br>
if (Queue) {<br>
Queue->push_back(S);<br>
return true;<br>
<br>
Modified: cfe/trunk/tools/libclang/IndexBody.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexBody.cpp?rev=254041&r1=254040&r2=254041&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexBody.cpp?rev=254041&r1=254040&r2=254041&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/tools/libclang/IndexBody.cpp (original)<br>
+++ cfe/trunk/tools/libclang/IndexBody.cpp Tue Nov 24 17:50:47 2015<br>
@@ -125,10 +125,11 @@ public:<br>
return true;<br>
}<br>
<br>
- bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {<br>
+ bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,<br>
+ DataRecursionQueue *Q = nullptr) {<br>
if (E->getOperatorLoc().isInvalid())<br>
return true; // implicit.<br>
- return base::TraverseCXXOperatorCallExpr(E);<br>
+ return base::TraverseCXXOperatorCallExpr(E, Q);<br>
}<br>
<br>
bool VisitDeclStmt(DeclStmt *S) {<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div></div></div><span class=""><font color="#888888">-- <br><div><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div></div>
</font></span></div>
</blockquote></div><br></div></div>