]> granicus.if.org Git - clang/commitdiff
Factor out duplication between ExprIterator and ConstExprIterator.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 1 Feb 2019 21:58:17 +0000 (21:58 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 1 Feb 2019 21:58:17 +0000 (21:58 +0000)
This also exposes a more general iterator cast mechanism suitable for
use in http://reviews.llvm.org/D56571.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@352925 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Stmt.h
lib/CodeGen/CGCoroutine.cpp

index 27d4f506a4283b0c15aabdf11206b0eb2b27bd12..66b53c088163e2011721543afb461b31d5163806 100644 (file)
@@ -986,38 +986,31 @@ public:
   struct EmptyShell {};
 
 protected:
-  /// Iterator for iterating over Stmt * arrays that contain only Expr *
+  /// Iterator for iterating over Stmt * arrays that contain only T *.
   ///
   /// This is needed because AST nodes use Stmt* arrays to store
   /// references to children (to be compatible with StmtIterator).
-  struct ExprIterator
-      : llvm::iterator_adaptor_base<ExprIterator, Stmt **,
-                                    std::random_access_iterator_tag, Expr *> {
-    ExprIterator() : iterator_adaptor_base(nullptr) {}
-    ExprIterator(Stmt **I) : iterator_adaptor_base(I) {}
-
-    reference operator*() const {
-      assert((*I)->getStmtClass() >= firstExprConstant &&
-             (*I)->getStmtClass() <= lastExprConstant);
-      return *reinterpret_cast<Expr **>(I);
-    }
-  };
+  template<typename T, typename TPtr = T *, typename StmtPtr = Stmt *>
+  struct CastIterator
+      : llvm::iterator_adaptor_base<CastIterator<T, TPtr, StmtPtr>, StmtPtr *,
+                                    std::random_access_iterator_tag, TPtr> {
+    using Base = typename CastIterator::iterator_adaptor_base;
+
+    CastIterator() : Base(nullptr) {}
+    CastIterator(StmtPtr *I) : Base(I) {}
 
-  /// Const iterator for iterating over Stmt * arrays that contain only Expr *
-  struct ConstExprIterator
-      : llvm::iterator_adaptor_base<ConstExprIterator, const Stmt *const *,
-                                    std::random_access_iterator_tag,
-                                    const Expr *const> {
-    ConstExprIterator() : iterator_adaptor_base(nullptr) {}
-    ConstExprIterator(const Stmt *const *I) : iterator_adaptor_base(I) {}
-
-    reference operator*() const {
-      assert((*I)->getStmtClass() >= firstExprConstant &&
-             (*I)->getStmtClass() <= lastExprConstant);
-      return *reinterpret_cast<const Expr *const *>(I);
+    typename Base::value_type operator*() const {
+      return cast<T>(*this->I);
     }
   };
 
+  /// Const iterator for iterating over Stmt * arrays that contain only T *.
+  template <typename T>
+  using ConstCastIterator = CastIterator<T, const T *const, const Stmt *const>;
+
+  using ExprIterator = CastIterator<Expr>;
+  using ConstExprIterator = ConstCastIterator<Expr>;
+
 private:
   /// Whether statistic collection is enabled.
   static bool StatisticsEnabled;
index a0668ea4ace2ea242189c7438f4117213fbd243e..8ac9b5b534e1a7a250767baa83dcee8c28276678 100644 (file)
@@ -732,7 +732,7 @@ RValue CodeGenFunction::EmitCoroutineIntrinsic(const CallExpr *E,
     Args.push_back(llvm::ConstantTokenNone::get(getLLVMContext()));
     break;
   }
-  for (auto &Arg : E->arguments())
+  for (const Expr *Arg : E->arguments())
     Args.push_back(EmitScalarExpr(Arg));
 
   llvm::Value *F = CGM.getIntrinsic(IID);