johannes updated this revision to Diff 115018.
johannes added a comment.

use CXXOperatorCallExpr::isPrefixOp() to determine whether it's infix or postfix
directly traverse statement children instead of copying

https://reviews.llvm.org/D37663

Files:
  include/clang/AST/ExprCXX.h
  include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
  include/clang/AST/RecursiveASTVisitor.h
  lib/AST/ExprCXX.cpp

Index: lib/AST/ExprCXX.cpp
===================================================================
--- lib/AST/ExprCXX.cpp
+++ lib/AST/ExprCXX.cpp
@@ -41,6 +41,12 @@
   }
 }
 
+bool CXXOperatorCallExpr::isPrefixOp() const {
+  return getNumArgs() == 1 && getOperator() != OO_Call &&
+         getOperator() != OO_Arrow;
+}
+
+
 bool CXXTypeidExpr::isPotentiallyEvaluated() const {
   if (isTypeOperand())
     return false;
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -315,8 +315,6 @@
 
 // ---- Methods on Stmts ----
 
-  Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
-
 private:
   template<typename T, typename U>
   struct has_same_member_pointer_type : std::false_type {};
@@ -2080,15 +2078,26 @@
       TRY_TO(WalkUpFrom##STMT(S));                                             \
     { CODE; }                                                                  \
     if (ShouldVisitChildren) {                                                 \
-      for (Stmt * SubStmt : getDerived().getStmtChildren(S)) {                 \
-        TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt);                              \
+      auto ChildIterator = S->child_begin();                                   \
+      /* Make the operator come second for infix and postfix overloaded        \
+       * operators. */                                                         \
+      if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {                       \
+        if (CE->isInfixBinaryOp() || !CE->isPrefixOp()) {                      \
+          Stmt *Operator = *ChildIterator;                                     \
+          TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(*++ChildIterator);                   \
+          TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Operator);                           \
+          ++ChildIterator;                                                     \
+        }                                                                      \
+      }                                                                        \
+      for (auto ChildEnd = S->child_end(); ChildIterator != ChildEnd;          \
+           ++ChildIterator) {                                                  \
+        TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(*ChildIterator);                       \
       }                                                                        \
     }                                                                          \
     if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder())       \
       TRY_TO(WalkUpFrom##STMT(S));                                             \
     return ReturnValue;                                                        \
   }
-
 DEF_TRAVERSE_STMT(GCCAsmStmt, {
   TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
   for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
Index: include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
===================================================================
--- include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
+++ include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
@@ -111,33 +111,6 @@
     return true;
   }
 
-  Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
-
-  SmallVector<Stmt *, 8> getStmtChildren(CXXOperatorCallExpr *CE) {
-    SmallVector<Stmt *, 8> Children(CE->children());
-    bool Swap;
-    // Switch the operator and the first operand for all infix and postfix
-    // operations.
-    switch (CE->getOperator()) {
-    case OO_Arrow:
-    case OO_Call:
-    case OO_Subscript:
-      Swap = true;
-      break;
-    case OO_PlusPlus:
-    case OO_MinusMinus:
-      // These are postfix unless there is exactly one argument.
-      Swap = Children.size() != 2;
-      break;
-    default:
-      Swap = CE->isInfixBinaryOp();
-      break;
-    }
-    if (Swap && Children.size() > 1)
-      std::swap(Children[0], Children[1]);
-    return Children;
-  }
-
 private:
   bool TraverseAdditionalLexicallyNestedDeclarations() {
     // FIXME: Ideally the gathered declarations and the declarations in the
Index: include/clang/AST/ExprCXX.h
===================================================================
--- include/clang/AST/ExprCXX.h
+++ include/clang/AST/ExprCXX.h
@@ -87,6 +87,8 @@
   /// \brief Is this written as an infix binary operator?
   bool isInfixBinaryOp() const;
 
+  bool isPrefixOp() const;
+
   /// \brief Returns the location of the operator symbol in the expression.
   ///
   /// When \c getOperator()==OO_Call, this is the location of the right
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D37663: [... Johannes Altmanninger via Phabricator via cfe-commits
    • [PATCH] D376... Manuel Klimek via Phabricator via cfe-commits
    • [PATCH] D376... Johannes Altmanninger via Phabricator via cfe-commits
    • [PATCH] D376... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D376... Johannes Altmanninger via Phabricator via cfe-commits
    • [PATCH] D376... Johannes Altmanninger via Phabricator via cfe-commits

Reply via email to