Try replacing all C-style casts
diff --git a/src/abi/stack.h b/src/abi/stack.h
index ae488e8..4d346f2 100644
--- a/src/abi/stack.h
+++ b/src/abi/stack.h
@@ -59,7 +59,7 @@
     added =
       builder.makeBinary(SubInt32,
                          builder.makeGlobalGet(stackPointer->name, pointerType),
-                         builder.makeConst(int32_t(size)));
+                         builder.makeConst(static_cast<int32_t>(size)));
   } else {
     WASM_UNREACHABLE("unhandled pointerType");
   }
@@ -70,7 +70,7 @@
       stackPointer->name,
       builder.makeBinary(AddInt32,
                          builder.makeLocalGet(local, pointerType),
-                         builder.makeConst(int32_t(size))));
+                         builder.makeConst(static_cast<int32_t>(size))));
   };
   // add stack restores to the returns
   FindAllPointers<Return> finder(func->body);
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 505872c..35dd5aa 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -221,7 +221,7 @@
   return Type(HeapType::nofunc, Nullable).getID();
 }
 BinaryenType BinaryenTypeUnreachable(void) { return Type::unreachable; }
-BinaryenType BinaryenTypeAuto(void) { return uintptr_t(-1); }
+BinaryenType BinaryenTypeAuto(void) { return static_cast<uintptr_t>(-1); }
 
 BinaryenType BinaryenTypeCreate(BinaryenType* types, BinaryenIndex numTypes) {
   std::vector<Type> typeVec;
@@ -247,7 +247,7 @@
 WASM_DEPRECATED BinaryenType BinaryenInt64(void) { return Type::i64; }
 WASM_DEPRECATED BinaryenType BinaryenFloat32(void) { return Type::f32; }
 WASM_DEPRECATED BinaryenType BinaryenFloat64(void) { return Type::f64; }
-WASM_DEPRECATED BinaryenType BinaryenUndefined(void) { return uint32_t(-1); }
+WASM_DEPRECATED BinaryenType BinaryenUndefined(void) { return static_cast<uint32_t>(-1); }
 
 // Packed types
 
@@ -512,7 +512,7 @@
 // Modules
 
 BinaryenModuleRef BinaryenModuleCreate(void) { return new Module(); }
-void BinaryenModuleDispose(BinaryenModuleRef module) { delete (Module*)module; }
+void BinaryenModuleDispose(BinaryenModuleRef module) { delete static_cast<Module*>(module); }
 
 // Literals
 
@@ -1076,12 +1076,12 @@
                                     BinaryenExpressionRef* children,
                                     BinaryenIndex numChildren,
                                     BinaryenType type) {
-  auto* ret = ((Module*)module)->allocator.alloc<Block>();
+  auto* ret = (static_cast<Module*>(module))->allocator.alloc<Block>();
   if (name) {
     ret->name = name;
   }
   for (BinaryenIndex i = 0; i < numChildren; i++) {
-    ret->list.push_back((Expression*)children[i]);
+    ret->list.push_back(reinterpret_cast<Expression**>(children)[i]);
   }
   if (type != BinaryenTypeAuto()) {
     ret->finalize(Type(type));
@@ -1094,25 +1094,25 @@
                                  BinaryenExpressionRef condition,
                                  BinaryenExpressionRef ifTrue,
                                  BinaryenExpressionRef ifFalse) {
-  return static_cast<Expression*>(Builder(*(Module*)module)
-                                    .makeIf((Expression*)condition,
-                                            (Expression*)ifTrue,
-                                            (Expression*)ifFalse));
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module))
+                                    .makeIf(static_cast<Expression*>(condition),
+                                            static_cast<Expression*>(ifTrue),
+                                            static_cast<Expression*>(ifFalse)));
 }
 BinaryenExpressionRef BinaryenLoop(BinaryenModuleRef module,
                                    const char* name,
                                    BinaryenExpressionRef body) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeLoop(name ? Name(name) : Name(), (Expression*)body));
+    Builder(*static_cast<Module*>(module))
+      .makeLoop(name ? Name(name) : Name(), static_cast<Expression*>(body)));
 }
 BinaryenExpressionRef BinaryenBreak(BinaryenModuleRef module,
                                     const char* name,
                                     BinaryenExpressionRef condition,
                                     BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeBreak(name, (Expression*)value, (Expression*)condition));
+    Builder(*static_cast<Module*>(module))
+      .makeBreak(name, static_cast<Expression*>(value), static_cast<Expression*>(condition)));
 }
 BinaryenExpressionRef BinaryenSwitch(BinaryenModuleRef module,
                                      const char** names,
@@ -1120,13 +1120,13 @@
                                      const char* defaultName,
                                      BinaryenExpressionRef condition,
                                      BinaryenExpressionRef value) {
-  auto* ret = ((Module*)module)->allocator.alloc<Switch>();
+  auto* ret = (static_cast<Module*>(module))->allocator.alloc<Switch>();
   for (BinaryenIndex i = 0; i < numNames; i++) {
     ret->targets.push_back(names[i]);
   }
   ret->default_ = defaultName;
-  ret->condition = (Expression*)condition;
-  ret->value = (Expression*)value;
+  ret->condition = static_cast<Expression*>(condition);
+  ret->value = static_cast<Expression*>(value);
   ret->finalize();
   return static_cast<Expression*>(ret);
 }
@@ -1136,10 +1136,10 @@
                                               BinaryenIndex numOperands,
                                               BinaryenType returnType,
                                               bool isReturn) {
-  auto* ret = ((Module*)module)->allocator.alloc<Call>();
+  auto* ret = (static_cast<Module*>(module))->allocator.alloc<Call>();
   ret->target = target;
   for (BinaryenIndex i = 0; i < numOperands; i++) {
-    ret->operands.push_back((Expression*)operands[i]);
+    ret->operands.push_back(reinterpret_cast<Expression**>(operands)[i]);
   }
   ret->type = Type(returnType);
   ret->isReturn = isReturn;
@@ -1171,11 +1171,11 @@
                          BinaryenType params,
                          BinaryenType results,
                          bool isReturn) {
-  auto* ret = ((Module*)module)->allocator.alloc<CallIndirect>();
+  auto* ret = (static_cast<Module*>(module))->allocator.alloc<CallIndirect>();
   ret->table = table;
-  ret->target = (Expression*)target;
+  ret->target = static_cast<Expression*>(target);
   for (BinaryenIndex i = 0; i < numOperands; i++) {
-    ret->operands.push_back((Expression*)operands[i]);
+    ret->operands.push_back(reinterpret_cast<Expression**>(operands)[i]);
   }
   ret->heapType = Signature(Type(params), Type(results));
   ret->type = Type(results);
@@ -1208,33 +1208,33 @@
                                        BinaryenIndex index,
                                        BinaryenType type) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeLocalGet(index, Type(type)));
+    Builder(*static_cast<Module*>(module)).makeLocalGet(index, Type(type)));
 }
 BinaryenExpressionRef BinaryenLocalSet(BinaryenModuleRef module,
                                        BinaryenIndex index,
                                        BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeLocalSet(index, (Expression*)value));
+    Builder(*static_cast<Module*>(module)).makeLocalSet(index, static_cast<Expression*>(value)));
 }
 BinaryenExpressionRef BinaryenLocalTee(BinaryenModuleRef module,
                                        BinaryenIndex index,
                                        BinaryenExpressionRef value,
                                        BinaryenType type) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeLocalTee(index, (Expression*)value, Type(type)));
+    Builder(*static_cast<Module*>(module))
+      .makeLocalTee(index, static_cast<Expression*>(value), Type(type)));
 }
 BinaryenExpressionRef BinaryenGlobalGet(BinaryenModuleRef module,
                                         const char* name,
                                         BinaryenType type) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeGlobalGet(name, Type(type)));
+    Builder(*static_cast<Module*>(module)).makeGlobalGet(name, Type(type)));
 }
 BinaryenExpressionRef BinaryenGlobalSet(BinaryenModuleRef module,
                                         const char* name,
                                         BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeGlobalSet(name, (Expression*)value));
+    Builder(*static_cast<Module*>(module)).makeGlobalSet(name, static_cast<Expression*>(value)));
 }
 
 // All memory instructions should pass their memory name parameter through this
@@ -1260,12 +1260,12 @@
                                    BinaryenExpressionRef ptr,
                                    const char* memoryName) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeLoad(bytes,
                 !!signed_,
                 offset,
                 align ? align : bytes,
-                (Expression*)ptr,
+                static_cast<Expression*>(ptr),
                 Type(type),
                 getMemoryName(module, memoryName)));
 }
@@ -1278,53 +1278,53 @@
                                     BinaryenType type,
                                     const char* memoryName) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeStore(bytes,
                  offset,
                  align ? align : bytes,
-                 (Expression*)ptr,
-                 (Expression*)value,
+                 static_cast<Expression*>(ptr),
+                 static_cast<Expression*>(value),
                  Type(type),
                  getMemoryName(module, memoryName)));
 }
 BinaryenExpressionRef BinaryenConst(BinaryenModuleRef module,
                                     BinaryenLiteral value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeConst(fromBinaryenLiteral(value)));
+    Builder(*static_cast<Module*>(module)).makeConst(fromBinaryenLiteral(value)));
 }
 BinaryenExpressionRef BinaryenUnary(BinaryenModuleRef module,
                                     BinaryenOp op,
                                     BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeUnary(UnaryOp(op), (Expression*)value));
+    Builder(*static_cast<Module*>(module)).makeUnary(UnaryOp(op), static_cast<Expression*>(value)));
 }
 BinaryenExpressionRef BinaryenBinary(BinaryenModuleRef module,
                                      BinaryenOp op,
                                      BinaryenExpressionRef left,
                                      BinaryenExpressionRef right) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeBinary(BinaryOp(op), (Expression*)left, (Expression*)right));
+    Builder(*static_cast<Module*>(module))
+      .makeBinary(BinaryOp(op), static_cast<Expression*>(left), static_cast<Expression*>(right)));
 }
 BinaryenExpressionRef BinaryenSelect(BinaryenModuleRef module,
                                      BinaryenExpressionRef condition,
                                      BinaryenExpressionRef ifTrue,
                                      BinaryenExpressionRef ifFalse) {
-  auto* ret = ((Module*)module)->allocator.alloc<Select>();
-  ret->condition = (Expression*)condition;
-  ret->ifTrue = (Expression*)ifTrue;
-  ret->ifFalse = (Expression*)ifFalse;
+  auto* ret = (static_cast<Module*>(module))->allocator.alloc<Select>();
+  ret->condition = static_cast<Expression*>(condition);
+  ret->ifTrue = static_cast<Expression*>(ifTrue);
+  ret->ifFalse = static_cast<Expression*>(ifFalse);
   ret->finalize();
   return static_cast<Expression*>(ret);
 }
 BinaryenExpressionRef BinaryenDrop(BinaryenModuleRef module,
                                    BinaryenExpressionRef value) {
-  auto* ret = Builder(*(Module*)module).makeDrop((Expression*)value);
+  auto* ret = Builder(*static_cast<Module*>(module)).makeDrop(static_cast<Expression*>(value));
   return static_cast<Expression*>(ret);
 }
 BinaryenExpressionRef BinaryenReturn(BinaryenModuleRef module,
                                      BinaryenExpressionRef value) {
-  auto* ret = Builder(*(Module*)module).makeReturn((Expression*)value);
+  auto* ret = Builder(*static_cast<Module*>(module)).makeReturn(static_cast<Expression*>(value));
   return static_cast<Expression*>(ret);
 }
 
@@ -1336,7 +1336,7 @@
 BinaryenExpressionRef BinaryenMemorySize(BinaryenModuleRef module,
                                          const char* memoryName,
                                          bool memoryIs64) {
-  auto* ret = Builder(*(Module*)module)
+  auto* ret = Builder(*static_cast<Module*>(module))
                 .makeMemorySize(getMemoryName(module, memoryName),
                                 getMemoryInfo(memoryIs64));
   return static_cast<Expression*>(ret);
@@ -1345,17 +1345,17 @@
                                          BinaryenExpressionRef delta,
                                          const char* memoryName,
                                          bool memoryIs64) {
-  auto* ret = Builder(*(Module*)module)
-                .makeMemoryGrow((Expression*)delta,
+  auto* ret = Builder(*static_cast<Module*>(module))
+                .makeMemoryGrow(static_cast<Expression*>(delta),
                                 getMemoryName(module, memoryName),
                                 getMemoryInfo(memoryIs64));
   return static_cast<Expression*>(ret);
 }
 BinaryenExpressionRef BinaryenNop(BinaryenModuleRef module) {
-  return static_cast<Expression*>(Builder(*(Module*)module).makeNop());
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module)).makeNop());
 }
 BinaryenExpressionRef BinaryenUnreachable(BinaryenModuleRef module) {
-  return static_cast<Expression*>(Builder(*(Module*)module).makeUnreachable());
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module)).makeUnreachable());
 }
 BinaryenExpressionRef BinaryenAtomicLoad(BinaryenModuleRef module,
                                          uint32_t bytes,
@@ -1365,10 +1365,10 @@
                                          const char* memoryName,
                                          BinaryenMemoryOrder order) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeAtomicLoad(bytes,
                       offset,
-                      (Expression*)ptr,
+                      static_cast<Expression*>(ptr),
                       Type(type),
                       getMemoryName(module, memoryName),
                       static_cast<MemoryOrder>(order)));
@@ -1382,11 +1382,11 @@
                                           const char* memoryName,
                                           BinaryenMemoryOrder order) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeAtomicStore(bytes,
                        offset,
-                       (Expression*)ptr,
-                       (Expression*)value,
+                       static_cast<Expression*>(ptr),
+                       static_cast<Expression*>(value),
                        Type(type),
                        getMemoryName(module, memoryName),
                        static_cast<MemoryOrder>(order)));
@@ -1400,12 +1400,12 @@
                                         BinaryenType type,
                                         const char* memoryName,
                                         BinaryenMemoryOrder order) {
-  return Builder(*(Module*)module)
+  return Builder(*static_cast<Module*>(module))
     .makeAtomicRMW(AtomicRMWOp(op),
                    bytes,
                    offset,
-                   (Expression*)ptr,
-                   (Expression*)value,
+                   static_cast<Expression*>(ptr),
+                   static_cast<Expression*>(value),
                    Type(type),
                    getMemoryName(module, memoryName),
                    static_cast<MemoryOrder>(order));
@@ -1420,12 +1420,12 @@
                                             const char* memoryName,
                                             BinaryenMemoryOrder order) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeAtomicCmpxchg(bytes,
                          offset,
-                         (Expression*)ptr,
-                         (Expression*)expected,
-                         (Expression*)replacement,
+                         static_cast<Expression*>(ptr),
+                         static_cast<Expression*>(expected),
+                         static_cast<Expression*>(replacement),
                          Type(type),
                          getMemoryName(module, memoryName),
                          static_cast<MemoryOrder>(order)));
@@ -1437,10 +1437,10 @@
                                          BinaryenType expectedType,
                                          const char* memoryName) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeAtomicWait((Expression*)ptr,
-                      (Expression*)expected,
-                      (Expression*)timeout,
+    Builder(*static_cast<Module*>(module))
+      .makeAtomicWait(static_cast<Expression*>(ptr),
+                      static_cast<Expression*>(expected),
+                      static_cast<Expression*>(timeout),
                       Type(expectedType),
                       0,
                       getMemoryName(module, memoryName)));
@@ -1450,22 +1450,22 @@
                                            BinaryenExpressionRef notifyCount,
                                            const char* memoryName) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeAtomicNotify((Expression*)ptr,
-                        (Expression*)notifyCount,
+    Builder(*static_cast<Module*>(module))
+      .makeAtomicNotify(static_cast<Expression*>(ptr),
+                        static_cast<Expression*>(notifyCount),
                         0,
                         getMemoryName(module, memoryName)));
 }
 BinaryenExpressionRef BinaryenAtomicFence(BinaryenModuleRef module) {
-  return static_cast<Expression*>(Builder(*(Module*)module).makeAtomicFence());
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module)).makeAtomicFence());
 }
 BinaryenExpressionRef BinaryenSIMDExtract(BinaryenModuleRef module,
                                           BinaryenOp op,
                                           BinaryenExpressionRef vec,
                                           uint8_t index) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeSIMDExtract(SIMDExtractOp(op), (Expression*)vec, index));
+    Builder(*static_cast<Module*>(module))
+      .makeSIMDExtract(SIMDExtractOp(op), static_cast<Expression*>(vec), index));
 }
 BinaryenExpressionRef BinaryenSIMDReplace(BinaryenModuleRef module,
                                           BinaryenOp op,
@@ -1473,9 +1473,9 @@
                                           uint8_t index,
                                           BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeSIMDReplace(
-        SIMDReplaceOp(op), (Expression*)vec, index, (Expression*)value));
+        SIMDReplaceOp(op), static_cast<Expression*>(vec), index, static_cast<Expression*>(value)));
 }
 BinaryenExpressionRef BinaryenSIMDShuffle(BinaryenModuleRef module,
                                           BinaryenExpressionRef left,
@@ -1485,8 +1485,8 @@
   std::array<uint8_t, 16> mask;
   memcpy(mask.data(), mask_, 16);
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeSIMDShuffle((Expression*)left, (Expression*)right, mask));
+    Builder(*static_cast<Module*>(module))
+      .makeSIMDShuffle(static_cast<Expression*>(left), static_cast<Expression*>(right), mask));
 }
 BinaryenExpressionRef BinaryenSIMDTernary(BinaryenModuleRef module,
                                           BinaryenOp op,
@@ -1494,17 +1494,17 @@
                                           BinaryenExpressionRef b,
                                           BinaryenExpressionRef c) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeSIMDTernary(
-        SIMDTernaryOp(op), (Expression*)a, (Expression*)b, (Expression*)c));
+        SIMDTernaryOp(op), static_cast<Expression*>(a), static_cast<Expression*>(b), static_cast<Expression*>(c)));
 }
 BinaryenExpressionRef BinaryenSIMDShift(BinaryenModuleRef module,
                                         BinaryenOp op,
                                         BinaryenExpressionRef vec,
                                         BinaryenExpressionRef shift) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeSIMDShift(SIMDShiftOp(op), (Expression*)vec, (Expression*)shift));
+    Builder(*static_cast<Module*>(module))
+      .makeSIMDShift(SIMDShiftOp(op), static_cast<Expression*>(vec), static_cast<Expression*>(shift)));
 }
 BinaryenExpressionRef BinaryenSIMDLoad(BinaryenModuleRef module,
                                        BinaryenOp op,
@@ -1513,11 +1513,11 @@
                                        BinaryenExpressionRef ptr,
                                        const char* memoryName) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeSIMDLoad(SIMDLoadOp(op),
                     Address(offset),
                     Address(align),
-                    (Expression*)ptr,
+                    static_cast<Expression*>(ptr),
                     getMemoryName(module, memoryName)));
 }
 BinaryenExpressionRef BinaryenSIMDLoadStoreLane(BinaryenModuleRef module,
@@ -1529,13 +1529,13 @@
                                                 BinaryenExpressionRef vec,
                                                 const char* memoryName) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeSIMDLoadStoreLane(SIMDLoadStoreLaneOp(op),
                              Address(offset),
                              Address(align),
                              index,
-                             (Expression*)ptr,
-                             (Expression*)vec,
+                             static_cast<Expression*>(ptr),
+                             static_cast<Expression*>(vec),
                              getMemoryName(module, memoryName)));
 }
 BinaryenExpressionRef BinaryenMemoryInit(BinaryenModuleRef module,
@@ -1545,18 +1545,18 @@
                                          BinaryenExpressionRef size,
                                          const char* memoryName) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeMemoryInit(Name(segment),
-                      (Expression*)dest,
-                      (Expression*)offset,
-                      (Expression*)size,
+                      static_cast<Expression*>(dest),
+                      static_cast<Expression*>(offset),
+                      static_cast<Expression*>(size),
                       getMemoryName(module, memoryName)));
 }
 
 BinaryenExpressionRef BinaryenDataDrop(BinaryenModuleRef module,
                                        const char* segment) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeDataDrop(Name(segment)));
+    Builder(*static_cast<Module*>(module)).makeDataDrop(Name(segment)));
 }
 
 BinaryenExpressionRef BinaryenMemoryCopy(BinaryenModuleRef module,
@@ -1566,10 +1566,10 @@
                                          const char* destMemory,
                                          const char* sourceMemory) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeMemoryCopy((Expression*)dest,
-                      (Expression*)source,
-                      (Expression*)size,
+    Builder(*static_cast<Module*>(module))
+      .makeMemoryCopy(static_cast<Expression*>(dest),
+                      static_cast<Expression*>(source),
+                      static_cast<Expression*>(size),
                       getMemoryName(module, destMemory),
                       getMemoryName(module, sourceMemory)));
 }
@@ -1580,10 +1580,10 @@
                                          BinaryenExpressionRef size,
                                          const char* memoryName) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeMemoryFill((Expression*)dest,
-                      (Expression*)value,
-                      (Expression*)size,
+    Builder(*static_cast<Module*>(module))
+      .makeMemoryFill(static_cast<Expression*>(dest),
+                      static_cast<Expression*>(value),
+                      static_cast<Expression*>(size),
                       getMemoryName(module, memoryName)));
 }
 
@@ -1593,21 +1593,21 @@
   std::vector<Expression*> ops;
   ops.resize(numOperands);
   for (size_t i = 0; i < numOperands; ++i) {
-    ops[i] = (Expression*)operands[i];
+    ops[i] = reinterpret_cast<Expression**>(operands)[i];
   }
-  return static_cast<Expression*>(Builder(*(Module*)module).makeTupleMake(ops));
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module)).makeTupleMake(ops));
 }
 
 BinaryenExpressionRef BinaryenTupleExtract(BinaryenModuleRef module,
                                            BinaryenExpressionRef tuple,
                                            BinaryenIndex index) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeTupleExtract((Expression*)tuple, index));
+    Builder(*static_cast<Module*>(module)).makeTupleExtract(static_cast<Expression*>(tuple), index));
 }
 
 BinaryenExpressionRef BinaryenPop(BinaryenModuleRef module, BinaryenType type) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makePop(Type(type)));
+    Builder(*static_cast<Module*>(module)).makePop(Type(type)));
 }
 
 BinaryenExpressionRef BinaryenRefNull(BinaryenModuleRef module,
@@ -1615,20 +1615,20 @@
   Type type_(type);
   assert(type_.isNullable());
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeRefNull(type_.getHeapType()));
+    Builder(*static_cast<Module*>(module)).makeRefNull(type_.getHeapType()));
 }
 
 BinaryenExpressionRef BinaryenRefIsNull(BinaryenModuleRef module,
                                         BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeRefIsNull((Expression*)value));
+    Builder(*static_cast<Module*>(module)).makeRefIsNull(static_cast<Expression*>(value)));
 }
 
 BinaryenExpressionRef BinaryenRefAs(BinaryenModuleRef module,
                                     BinaryenOp op,
                                     BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeRefAs(RefAsOp(op), (Expression*)value));
+    Builder(*static_cast<Module*>(module)).makeRefAs(RefAsOp(op), static_cast<Expression*>(value)));
 }
 
 BinaryenExpressionRef BinaryenRefFunc(BinaryenModuleRef module,
@@ -1638,17 +1638,17 @@
   // other defined functions. See if the function exists already, and assume it
   // is non-imported if not. TODO: If we want to allow creating imports later,
   // we would need an API addition or change.
-  auto* wasm = (Module*)module;
+  auto* wasm = static_cast<Module*>(module);
   if ([[maybe_unused]] auto* f = wasm->getFunctionOrNull(func)) {
     assert(f->type.getHeapType() == HeapType(type));
     // Use the HeapType constructor, which will do a lookup on the module.
     return static_cast<Expression*>(
-      Builder(*(Module*)module).makeRefFunc(func));
+      Builder(*static_cast<Module*>(module)).makeRefFunc(func));
   } else {
     // Assume non-imported, and provide the full type for that.
     Type full = Type(HeapType(type), NonNullable, Exact);
     return static_cast<Expression*>(
-      Builder(*(Module*)module).makeRefFunc(func, full));
+      Builder(*static_cast<Module*>(module)).makeRefFunc(func, full));
   }
 }
 
@@ -1656,7 +1656,7 @@
                                     BinaryenExpressionRef left,
                                     BinaryenExpressionRef right) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeRefEq((Expression*)left, (Expression*)right));
+    Builder(*static_cast<Module*>(module)).makeRefEq(static_cast<Expression*>(left), static_cast<Expression*>(right)));
 }
 
 BinaryenExpressionRef BinaryenTableGet(BinaryenModuleRef module,
@@ -1664,8 +1664,8 @@
                                        BinaryenExpressionRef index,
                                        BinaryenType type) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeTableGet(name, (Expression*)index, Type(type)));
+    Builder(*static_cast<Module*>(module))
+      .makeTableGet(name, static_cast<Expression*>(index), Type(type)));
 }
 
 BinaryenExpressionRef BinaryenTableSet(BinaryenModuleRef module,
@@ -1673,14 +1673,14 @@
                                        BinaryenExpressionRef index,
                                        BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeTableSet(name, (Expression*)index, (Expression*)value));
+    Builder(*static_cast<Module*>(module))
+      .makeTableSet(name, static_cast<Expression*>(index), static_cast<Expression*>(value)));
 }
 
 BinaryenExpressionRef BinaryenTableSize(BinaryenModuleRef module,
                                         const char* name) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeTableSize(name));
+    Builder(*static_cast<Module*>(module)).makeTableSize(name));
 }
 
 BinaryenExpressionRef BinaryenTableGrow(BinaryenModuleRef module,
@@ -1688,12 +1688,12 @@
                                         BinaryenExpressionRef value,
                                         BinaryenExpressionRef delta) {
   if (value == nullptr) {
-    auto tableType = (*(Module*)module).getTableOrNull(name)->type;
+    auto tableType = (*static_cast<Module*>(module)).getTableOrNull(name)->type;
     value = BinaryenRefNull(module, (BinaryenType)tableType.getID());
   }
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeTableGrow(name, (Expression*)value, (Expression*)delta));
+    Builder(*static_cast<Module*>(module))
+      .makeTableGrow(name, static_cast<Expression*>(value), static_cast<Expression*>(delta)));
 }
 
 BinaryenExpressionRef BinaryenTry(BinaryenModuleRef module,
@@ -1704,16 +1704,16 @@
                                   BinaryenExpressionRef* catchBodies,
                                   BinaryenIndex numCatchBodies,
                                   const char* delegateTarget) {
-  auto* ret = ((Module*)module)->allocator.alloc<Try>();
+  auto* ret = (static_cast<Module*>(module))->allocator.alloc<Try>();
   if (name) {
     ret->name = name;
   }
-  ret->body = (Expression*)body;
+  ret->body = static_cast<Expression*>(body);
   for (BinaryenIndex i = 0; i < numCatchTags; i++) {
     ret->catchTags.push_back(catchTags[i]);
   }
   for (BinaryenIndex i = 0; i < numCatchBodies; i++) {
-    ret->catchBodies.push_back((Expression*)catchBodies[i]);
+    ret->catchBodies.push_back(reinterpret_cast<Expression**>(catchBodies)[i]);
   }
   if (delegateTarget) {
     ret->delegateTarget = delegateTarget;
@@ -1728,29 +1728,29 @@
                                     BinaryenIndex numOperands) {
   std::vector<Expression*> args;
   for (BinaryenIndex i = 0; i < numOperands; i++) {
-    args.push_back((Expression*)operands[i]);
+    args.push_back(reinterpret_cast<Expression**>(operands)[i]);
   }
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeThrow(tag, args));
+    Builder(*static_cast<Module*>(module)).makeThrow(tag, args));
 }
 
 BinaryenExpressionRef BinaryenRethrow(BinaryenModuleRef module,
                                       const char* target) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeRethrow(target));
+    Builder(*static_cast<Module*>(module)).makeRethrow(target));
 }
 
 BinaryenExpressionRef BinaryenRefI31(BinaryenModuleRef module,
                                      BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeRefI31((Expression*)value));
+    Builder(*static_cast<Module*>(module)).makeRefI31(static_cast<Expression*>(value)));
 }
 
 BinaryenExpressionRef BinaryenI31Get(BinaryenModuleRef module,
                                      BinaryenExpressionRef i31,
                                      bool signed_) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeI31Get((Expression*)i31, signed_ != 0));
+    Builder(*static_cast<Module*>(module)).makeI31Get(static_cast<Expression*>(i31), signed_ != 0));
 }
 BinaryenExpressionRef BinaryenCallRef(BinaryenModuleRef module,
                                       BinaryenExpressionRef target,
@@ -1759,11 +1759,11 @@
                                       BinaryenType type) {
   std::vector<Expression*> args;
   for (BinaryenIndex i = 0; i < numOperands; i++) {
-    args.push_back((Expression*)operands[i]);
+    args.push_back(reinterpret_cast<Expression**>(operands)[i]);
   }
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeCallRef((Expression*)target, args, Type(type), false));
+    Builder(*static_cast<Module*>(module))
+      .makeCallRef(static_cast<Expression*>(target), args, Type(type), false));
 }
 BinaryenExpressionRef BinaryenReturnCallRef(BinaryenModuleRef module,
                                             BinaryenExpressionRef target,
@@ -1772,23 +1772,23 @@
                                             BinaryenType type) {
   std::vector<Expression*> args;
   for (BinaryenIndex i = 0; i < numOperands; i++) {
-    args.push_back((Expression*)operands[i]);
+    args.push_back(reinterpret_cast<Expression**>(operands)[i]);
   }
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeCallRef((Expression*)target, args, Type(type), true));
+    Builder(*static_cast<Module*>(module))
+      .makeCallRef(static_cast<Expression*>(target), args, Type(type), true));
 }
 BinaryenExpressionRef BinaryenRefTest(BinaryenModuleRef module,
                                       BinaryenExpressionRef ref,
                                       BinaryenType castType) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeRefTest((Expression*)ref, Type(castType)));
+    Builder(*static_cast<Module*>(module)).makeRefTest(static_cast<Expression*>(ref), Type(castType)));
 }
 BinaryenExpressionRef BinaryenRefCast(BinaryenModuleRef module,
                                       BinaryenExpressionRef ref,
                                       BinaryenType type) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeRefCast((Expression*)ref, Type(type)));
+    Builder(*static_cast<Module*>(module)).makeRefCast(static_cast<Expression*>(ref), Type(type)));
 }
 BinaryenExpressionRef BinaryenBrOn(BinaryenModuleRef module,
                                    BinaryenOp op,
@@ -1796,8 +1796,8 @@
                                    BinaryenExpressionRef ref,
                                    BinaryenType castType) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeBrOn(BrOnOp(op), name, (Expression*)ref, Type(castType)));
+    Builder(*static_cast<Module*>(module))
+      .makeBrOn(BrOnOp(op), name, static_cast<Expression*>(ref), Type(castType)));
 }
 BinaryenExpressionRef BinaryenStructNew(BinaryenModuleRef module,
                                         BinaryenExpressionRef* operands,
@@ -1805,10 +1805,10 @@
                                         BinaryenHeapType type) {
   std::vector<Expression*> args;
   for (BinaryenIndex i = 0; i < numOperands; i++) {
-    args.push_back((Expression*)operands[i]);
+    args.push_back(reinterpret_cast<Expression**>(operands)[i]);
   }
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeStructNew(HeapType(type), args));
+    Builder(*static_cast<Module*>(module)).makeStructNew(HeapType(type), args));
 }
 BinaryenExpressionRef BinaryenStructGet(BinaryenModuleRef module,
                                         BinaryenIndex index,
@@ -1816,26 +1816,26 @@
                                         BinaryenType type,
                                         bool signed_) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeStructGet(
-        index, (Expression*)ref, MemoryOrder::Unordered, Type(type), signed_));
+        index, static_cast<Expression*>(ref), MemoryOrder::Unordered, Type(type), signed_));
 }
 BinaryenExpressionRef BinaryenStructSet(BinaryenModuleRef module,
                                         BinaryenIndex index,
                                         BinaryenExpressionRef ref,
                                         BinaryenExpressionRef value) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeStructSet(
-        index, (Expression*)ref, (Expression*)value, MemoryOrder::Unordered));
+        index, static_cast<Expression*>(ref), static_cast<Expression*>(value), MemoryOrder::Unordered));
 }
 BinaryenExpressionRef BinaryenArrayNew(BinaryenModuleRef module,
                                        BinaryenHeapType type,
                                        BinaryenExpressionRef size,
                                        BinaryenExpressionRef init) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeArrayNew(HeapType(type), (Expression*)size, (Expression*)init));
+    Builder(*static_cast<Module*>(module))
+      .makeArrayNew(HeapType(type), static_cast<Expression*>(size), static_cast<Expression*>(init)));
 }
 BinaryenExpressionRef BinaryenArrayNewData(BinaryenModuleRef module,
                                            BinaryenHeapType type,
@@ -1843,9 +1843,9 @@
                                            BinaryenExpressionRef offset,
                                            BinaryenExpressionRef size) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeArrayNewData(
-        HeapType(type), name, (Expression*)offset, (Expression*)size));
+        HeapType(type), name, static_cast<Expression*>(offset), static_cast<Expression*>(size)));
 }
 BinaryenExpressionRef BinaryenArrayNewElem(BinaryenModuleRef module,
                                            BinaryenHeapType type,
@@ -1853,9 +1853,9 @@
                                            BinaryenExpressionRef offset,
                                            BinaryenExpressionRef size) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
+    Builder(*static_cast<Module*>(module))
       .makeArrayNewElem(
-        HeapType(type), name, (Expression*)offset, (Expression*)size));
+        HeapType(type), name, static_cast<Expression*>(offset), static_cast<Expression*>(size)));
 }
 BinaryenExpressionRef BinaryenArrayNewFixed(BinaryenModuleRef module,
                                             BinaryenHeapType type,
@@ -1863,19 +1863,19 @@
                                             BinaryenIndex numValues) {
   std::vector<Expression*> vals;
   for (BinaryenIndex i = 0; i < numValues; i++) {
-    vals.push_back((Expression*)values[i]);
+    vals.push_back(reinterpret_cast<Expression**>(values)[i]);
   }
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeArrayNewFixed(HeapType(type), vals));
+    Builder(*static_cast<Module*>(module)).makeArrayNewFixed(HeapType(type), vals));
 }
 BinaryenExpressionRef BinaryenArrayGet(BinaryenModuleRef module,
                                        BinaryenExpressionRef ref,
                                        BinaryenExpressionRef index,
                                        BinaryenType type,
                                        bool signed_) {
-  return static_cast<Expression*>(Builder(*(Module*)module)
-                                    .makeArrayGet((Expression*)ref,
-                                                  (Expression*)index,
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module))
+                                    .makeArrayGet(static_cast<Expression*>(ref),
+                                                  static_cast<Expression*>(index),
                                                   MemoryOrder::Unordered,
                                                   Type(type),
                                                   signed_));
@@ -1884,16 +1884,16 @@
                                        BinaryenExpressionRef ref,
                                        BinaryenExpressionRef index,
                                        BinaryenExpressionRef value) {
-  return static_cast<Expression*>(Builder(*(Module*)module)
-                                    .makeArraySet((Expression*)ref,
-                                                  (Expression*)index,
-                                                  (Expression*)value,
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module))
+                                    .makeArraySet(static_cast<Expression*>(ref),
+                                                  static_cast<Expression*>(index),
+                                                  static_cast<Expression*>(value),
                                                   MemoryOrder::Unordered));
 }
 BinaryenExpressionRef BinaryenArrayLen(BinaryenModuleRef module,
                                        BinaryenExpressionRef ref) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeArrayLen((Expression*)ref));
+    Builder(*static_cast<Module*>(module)).makeArrayLen(static_cast<Expression*>(ref)));
 }
 BinaryenExpressionRef BinaryenArrayCopy(BinaryenModuleRef module,
                                         BinaryenExpressionRef destRef,
@@ -1901,23 +1901,23 @@
                                         BinaryenExpressionRef srcRef,
                                         BinaryenExpressionRef srcIndex,
                                         BinaryenExpressionRef length) {
-  return static_cast<Expression*>(Builder(*(Module*)module)
-                                    .makeArrayCopy((Expression*)destRef,
-                                                   (Expression*)destIndex,
-                                                   (Expression*)srcRef,
-                                                   (Expression*)srcIndex,
-                                                   (Expression*)length));
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module))
+                                    .makeArrayCopy(static_cast<Expression*>(destRef),
+                                                   static_cast<Expression*>(destIndex),
+                                                   static_cast<Expression*>(srcRef),
+                                                   static_cast<Expression*>(srcIndex),
+                                                   static_cast<Expression*>(length)));
 }
 BinaryenExpressionRef BinaryenArrayFill(BinaryenModuleRef module,
                                         BinaryenExpressionRef ref,
                                         BinaryenExpressionRef index,
                                         BinaryenExpressionRef value,
                                         BinaryenExpressionRef size) {
-  return static_cast<Expression*>(Builder(*(Module*)module)
-                                    .makeArrayFill((Expression*)ref,
-                                                   (Expression*)index,
-                                                   (Expression*)value,
-                                                   (Expression*)size));
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module))
+                                    .makeArrayFill(static_cast<Expression*>(ref),
+                                                   static_cast<Expression*>(index),
+                                                   static_cast<Expression*>(value),
+                                                   static_cast<Expression*>(size)));
 }
 BinaryenExpressionRef BinaryenArrayInitData(BinaryenModuleRef module,
                                             const char* name,
@@ -1925,12 +1925,12 @@
                                             BinaryenExpressionRef index,
                                             BinaryenExpressionRef offset,
                                             BinaryenExpressionRef size) {
-  return static_cast<Expression*>(Builder(*(Module*)module)
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module))
                                     .makeArrayInitData(name,
-                                                       (Expression*)ref,
-                                                       (Expression*)index,
-                                                       (Expression*)offset,
-                                                       (Expression*)size));
+                                                       static_cast<Expression*>(ref),
+                                                       static_cast<Expression*>(index),
+                                                       static_cast<Expression*>(offset),
+                                                       static_cast<Expression*>(size)));
 }
 BinaryenExpressionRef BinaryenArrayInitElem(BinaryenModuleRef module,
                                             const char* seg,
@@ -1938,21 +1938,21 @@
                                             BinaryenExpressionRef index,
                                             BinaryenExpressionRef offset,
                                             BinaryenExpressionRef size) {
-  return static_cast<Expression*>(Builder(*(Module*)module)
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module))
                                     .makeArrayInitElem(seg,
-                                                       (Expression*)ref,
-                                                       (Expression*)index,
-                                                       (Expression*)offset,
-                                                       (Expression*)size));
+                                                       static_cast<Expression*>(ref),
+                                                       static_cast<Expression*>(index),
+                                                       static_cast<Expression*>(offset),
+                                                       static_cast<Expression*>(size)));
 }
 BinaryenExpressionRef BinaryenStringNew(BinaryenModuleRef module,
                                         BinaryenOp op,
                                         BinaryenExpressionRef ptr,
                                         BinaryenExpressionRef start,
                                         BinaryenExpressionRef end) {
-  Builder builder(*(Module*)module);
+  Builder builder(*static_cast<Module*>(module));
   return static_cast<Expression*>(builder.makeStringNew(
-    StringNewOp(op), (Expression*)ptr, (Expression*)start, (Expression*)end));
+    StringNewOp(op), static_cast<Expression*>(ptr), static_cast<Expression*>(start), static_cast<Expression*>(end)));
 }
 BinaryenExpressionRef BinaryenStringConst(BinaryenModuleRef module,
                                           const char* name) {
@@ -1962,103 +1962,103 @@
   assert(valid);
   // TODO: Use wtf16.view() once we have C++20.
   return static_cast<Expression*>(
-    Builder(*(Module*)module).makeStringConst(wtf16.str()));
+    Builder(*static_cast<Module*>(module)).makeStringConst(wtf16.str()));
 }
 BinaryenExpressionRef BinaryenStringMeasure(BinaryenModuleRef module,
                                             BinaryenOp op,
                                             BinaryenExpressionRef ref) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeStringMeasure(StringMeasureOp(op), (Expression*)ref));
+    Builder(*static_cast<Module*>(module))
+      .makeStringMeasure(StringMeasureOp(op), static_cast<Expression*>(ref)));
 }
 BinaryenExpressionRef BinaryenStringEncode(BinaryenModuleRef module,
                                            BinaryenOp op,
                                            BinaryenExpressionRef ref,
                                            BinaryenExpressionRef ptr,
                                            BinaryenExpressionRef start) {
-  return static_cast<Expression*>(Builder(*(Module*)module)
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module))
                                     .makeStringEncode(StringEncodeOp(op),
-                                                      (Expression*)ref,
-                                                      (Expression*)ptr,
-                                                      (Expression*)start));
+                                                      static_cast<Expression*>(ref),
+                                                      static_cast<Expression*>(ptr),
+                                                      static_cast<Expression*>(start)));
 }
 BinaryenExpressionRef BinaryenStringConcat(BinaryenModuleRef module,
                                            BinaryenExpressionRef left,
                                            BinaryenExpressionRef right) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeStringConcat((Expression*)left, (Expression*)right));
+    Builder(*static_cast<Module*>(module))
+      .makeStringConcat(static_cast<Expression*>(left), static_cast<Expression*>(right)));
 }
 BinaryenExpressionRef BinaryenStringEq(BinaryenModuleRef module,
                                        BinaryenOp op,
                                        BinaryenExpressionRef left,
                                        BinaryenExpressionRef right) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeStringEq(StringEqOp(op), (Expression*)left, (Expression*)right));
+    Builder(*static_cast<Module*>(module))
+      .makeStringEq(StringEqOp(op), static_cast<Expression*>(left), static_cast<Expression*>(right)));
 }
 BinaryenExpressionRef BinaryenStringWTF16Get(BinaryenModuleRef module,
                                              BinaryenExpressionRef ref,
                                              BinaryenExpressionRef pos) {
   return static_cast<Expression*>(
-    Builder(*(Module*)module)
-      .makeStringWTF16Get((Expression*)ref, (Expression*)pos));
+    Builder(*static_cast<Module*>(module))
+      .makeStringWTF16Get(static_cast<Expression*>(ref), static_cast<Expression*>(pos)));
 }
 BinaryenExpressionRef BinaryenStringSliceWTF(BinaryenModuleRef module,
                                              BinaryenExpressionRef ref,
                                              BinaryenExpressionRef start,
                                              BinaryenExpressionRef end) {
-  return static_cast<Expression*>(Builder(*(Module*)module)
-                                    .makeStringSliceWTF((Expression*)ref,
-                                                        (Expression*)start,
-                                                        (Expression*)end));
+  return static_cast<Expression*>(Builder(*static_cast<Module*>(module))
+                                    .makeStringSliceWTF(static_cast<Expression*>(ref),
+                                                        static_cast<Expression*>(start),
+                                                        static_cast<Expression*>(end)));
 }
 
 // Expression utility
 
 BinaryenExpressionId BinaryenExpressionGetId(BinaryenExpressionRef expr) {
-  return ((Expression*)expr)->_id;
+  return (static_cast<Expression*>(expr))->_id;
 }
 BinaryenType BinaryenExpressionGetType(BinaryenExpressionRef expr) {
-  return ((Expression*)expr)->type.getID();
+  return (static_cast<Expression*>(expr))->type.getID();
 }
 void BinaryenExpressionSetType(BinaryenExpressionRef expr, BinaryenType type) {
-  ((Expression*)expr)->type = Type(type);
+  (static_cast<Expression*>(expr))->type = Type(type);
 }
 void BinaryenExpressionPrint(BinaryenExpressionRef expr) {
-  std::cout << *(Expression*)expr << '\n';
+  std::cout << *static_cast<Expression*>(expr) << '\n';
 }
 void BinaryenExpressionFinalize(BinaryenExpressionRef expr) {
-  ReFinalizeNode().visit((Expression*)expr);
+  ReFinalizeNode().visit(static_cast<Expression*>(expr));
 }
 
 BinaryenExpressionRef BinaryenExpressionCopy(BinaryenExpressionRef expr,
                                              BinaryenModuleRef module) {
-  return ExpressionManipulator::copy(expr, *(Module*)module);
+  return ExpressionManipulator::copy(expr, *static_cast<Module*>(module));
 }
 
 // Specific expression utility
 
 // Block
 const char* BinaryenBlockGetName(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Block>());
   return static_cast<Block*>(expression)->name.str.data();
 }
 void BinaryenBlockSetName(BinaryenExpressionRef expr, const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Block>());
   // may be null or empty
   static_cast<Block*>(expression)->name = name;
 }
 BinaryenIndex BinaryenBlockGetNumChildren(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Block>());
   return static_cast<Block*>(expression)->list.size();
 }
 BinaryenExpressionRef BinaryenBlockGetChildAt(BinaryenExpressionRef expr,
                                               BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Block>());
   assert(index < static_cast<Block*>(expression)->list.size());
   return static_cast<Block*>(expression)->list[index];
@@ -2066,143 +2066,143 @@
 void BinaryenBlockSetChildAt(BinaryenExpressionRef expr,
                              BinaryenIndex index,
                              BinaryenExpressionRef childExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Block>());
   assert(childExpr);
   auto& list = static_cast<Block*>(expression)->list;
   assert(index < list.size());
-  list[index] = (Expression*)childExpr;
+  list[index] = static_cast<Expression*>(childExpr);
 }
 BinaryenIndex BinaryenBlockAppendChild(BinaryenExpressionRef expr,
                                        BinaryenExpressionRef childExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Block>());
   assert(childExpr);
   auto& list = static_cast<Block*>(expression)->list;
   auto index = list.size();
-  list.push_back((Expression*)childExpr);
+  list.push_back(static_cast<Expression*>(childExpr));
   return index;
 }
 void BinaryenBlockInsertChildAt(BinaryenExpressionRef expr,
                                 BinaryenIndex index,
                                 BinaryenExpressionRef childExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Block>());
   assert(childExpr);
-  static_cast<Block*>(expression)->list.insertAt(index, (Expression*)childExpr);
+  static_cast<Block*>(expression)->list.insertAt(index, static_cast<Expression*>(childExpr));
 }
 BinaryenExpressionRef BinaryenBlockRemoveChildAt(BinaryenExpressionRef expr,
                                                  BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Block>());
   return static_cast<Block*>(expression)->list.removeAt(index);
 }
 // If
 BinaryenExpressionRef BinaryenIfGetCondition(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<If>());
   return static_cast<If*>(expression)->condition;
 }
 void BinaryenIfSetCondition(BinaryenExpressionRef expr,
                             BinaryenExpressionRef condExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<If>());
   assert(condExpr);
-  static_cast<If*>(expression)->condition = (Expression*)condExpr;
+  static_cast<If*>(expression)->condition = static_cast<Expression*>(condExpr);
 }
 BinaryenExpressionRef BinaryenIfGetIfTrue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<If>());
   return static_cast<If*>(expression)->ifTrue;
 }
 void BinaryenIfSetIfTrue(BinaryenExpressionRef expr,
                          BinaryenExpressionRef ifTrueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<If>());
   assert(ifTrueExpr);
-  static_cast<If*>(expression)->ifTrue = (Expression*)ifTrueExpr;
+  static_cast<If*>(expression)->ifTrue = static_cast<Expression*>(ifTrueExpr);
 }
 BinaryenExpressionRef BinaryenIfGetIfFalse(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<If>());
   return static_cast<If*>(expression)->ifFalse;
 }
 void BinaryenIfSetIfFalse(BinaryenExpressionRef expr,
                           BinaryenExpressionRef ifFalseExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<If>());
   // may be null
-  static_cast<If*>(expression)->ifFalse = (Expression*)ifFalseExpr;
+  static_cast<If*>(expression)->ifFalse = static_cast<Expression*>(ifFalseExpr);
 }
 // Loop
 const char* BinaryenLoopGetName(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Loop>());
   return static_cast<Loop*>(expression)->name.str.data();
 }
 void BinaryenLoopSetName(BinaryenExpressionRef expr, const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Loop>());
   // may be null or empty
   static_cast<Loop*>(expression)->name = name;
 }
 BinaryenExpressionRef BinaryenLoopGetBody(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Loop>());
   return static_cast<Loop*>(expression)->body;
 }
 void BinaryenLoopSetBody(BinaryenExpressionRef expr,
                          BinaryenExpressionRef bodyExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Loop>());
   assert(bodyExpr);
-  static_cast<Loop*>(expression)->body = (Expression*)bodyExpr;
+  static_cast<Loop*>(expression)->body = static_cast<Expression*>(bodyExpr);
 }
 // Break
 const char* BinaryenBreakGetName(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Break>());
   return static_cast<Break*>(expression)->name.str.data();
 }
 void BinaryenBreakSetName(BinaryenExpressionRef expr, const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Break>());
   assert(name);
   static_cast<Break*>(expression)->name = name;
 }
 BinaryenExpressionRef BinaryenBreakGetCondition(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Break>());
   return static_cast<Break*>(expression)->condition;
 }
 void BinaryenBreakSetCondition(BinaryenExpressionRef expr,
                                BinaryenExpressionRef condExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Break>());
   // may be null (br)
-  static_cast<Break*>(expression)->condition = (Expression*)condExpr;
+  static_cast<Break*>(expression)->condition = static_cast<Expression*>(condExpr);
 }
 BinaryenExpressionRef BinaryenBreakGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Break>());
   return static_cast<Break*>(expression)->value;
 }
 void BinaryenBreakSetValue(BinaryenExpressionRef expr,
                            BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Break>());
   // may be null
-  static_cast<Break*>(expression)->value = (Expression*)valueExpr;
+  static_cast<Break*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // Switch
 BinaryenIndex BinaryenSwitchGetNumNames(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   return static_cast<Switch*>(expression)->targets.size();
 }
 const char* BinaryenSwitchGetNameAt(BinaryenExpressionRef expr,
                                     BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   assert(index < static_cast<Switch*>(expression)->targets.size());
   return static_cast<Switch*>(expression)->targets[index].str.data();
@@ -2210,7 +2210,7 @@
 void BinaryenSwitchSetNameAt(BinaryenExpressionRef expr,
                              BinaryenIndex index,
                              const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   assert(index < static_cast<Switch*>(expression)->targets.size());
   assert(name);
@@ -2218,7 +2218,7 @@
 }
 BinaryenIndex BinaryenSwitchAppendName(BinaryenExpressionRef expr,
                                        const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   assert(name);
   auto& list = static_cast<Switch*>(expression)->targets;
@@ -2229,73 +2229,73 @@
 void BinaryenSwitchInsertNameAt(BinaryenExpressionRef expr,
                                 BinaryenIndex index,
                                 const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   assert(name);
   static_cast<Switch*>(expression)->targets.insertAt(index, name);
 }
 const char* BinaryenSwitchRemoveNameAt(BinaryenExpressionRef expr,
                                        BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   return static_cast<Switch*>(expression)->targets.removeAt(index).str.data();
 }
 const char* BinaryenSwitchGetDefaultName(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   return static_cast<Switch*>(expression)->default_.str.data();
 }
 void BinaryenSwitchSetDefaultName(BinaryenExpressionRef expr,
                                   const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   // may be null or empty
   static_cast<Switch*>(expression)->default_ = name;
 }
 BinaryenExpressionRef BinaryenSwitchGetCondition(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   return static_cast<Switch*>(expression)->condition;
 }
 void BinaryenSwitchSetCondition(BinaryenExpressionRef expr,
                                 BinaryenExpressionRef condExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   assert(condExpr);
-  static_cast<Switch*>(expression)->condition = (Expression*)condExpr;
+  static_cast<Switch*>(expression)->condition = static_cast<Expression*>(condExpr);
 }
 BinaryenExpressionRef BinaryenSwitchGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   return static_cast<Switch*>(expression)->value;
 }
 void BinaryenSwitchSetValue(BinaryenExpressionRef expr,
                             BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Switch>());
   // may be null
-  static_cast<Switch*>(expression)->value = (Expression*)valueExpr;
+  static_cast<Switch*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // Call
 const char* BinaryenCallGetTarget(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   return static_cast<Call*>(expression)->target.str.data();
 }
 void BinaryenCallSetTarget(BinaryenExpressionRef expr, const char* target) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   assert(target);
   static_cast<Call*>(expression)->target = target;
 }
 BinaryenIndex BinaryenCallGetNumOperands(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   return static_cast<Call*>(expression)->operands.size();
 }
 BinaryenExpressionRef BinaryenCallGetOperandAt(BinaryenExpressionRef expr,
                                                BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   assert(index < static_cast<Call*>(expression)->operands.size());
   return static_cast<Call*>(expression)->operands[index];
@@ -2303,83 +2303,83 @@
 void BinaryenCallSetOperandAt(BinaryenExpressionRef expr,
                               BinaryenIndex index,
                               BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   assert(index < static_cast<Call*>(expression)->operands.size());
   assert(operandExpr);
-  static_cast<Call*>(expression)->operands[index] = (Expression*)operandExpr;
+  static_cast<Call*>(expression)->operands[index] = static_cast<Expression*>(operandExpr);
 }
 BinaryenIndex BinaryenCallAppendOperand(BinaryenExpressionRef expr,
                                         BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   assert(operandExpr);
   auto& list = static_cast<Call*>(expression)->operands;
   auto index = list.size();
-  list.push_back((Expression*)operandExpr);
+  list.push_back(static_cast<Expression*>(operandExpr));
   return index;
 }
 void BinaryenCallInsertOperandAt(BinaryenExpressionRef expr,
                                  BinaryenIndex index,
                                  BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   assert(operandExpr);
   static_cast<Call*>(expression)
-    ->operands.insertAt(index, (Expression*)operandExpr);
+    ->operands.insertAt(index, static_cast<Expression*>(operandExpr));
 }
 BinaryenExpressionRef BinaryenCallRemoveOperandAt(BinaryenExpressionRef expr,
                                                   BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   return static_cast<Call*>(expression)->operands.removeAt(index);
 }
 bool BinaryenCallIsReturn(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   return static_cast<Call*>(expression)->isReturn;
 }
 void BinaryenCallSetReturn(BinaryenExpressionRef expr, bool isReturn) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Call>());
   static_cast<Call*>(expression)->isReturn = isReturn != 0;
 }
 // CallIndirect
 BinaryenExpressionRef
 BinaryenCallIndirectGetTarget(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   return static_cast<CallIndirect*>(expression)->target;
 }
 void BinaryenCallIndirectSetTarget(BinaryenExpressionRef expr,
                                    BinaryenExpressionRef targetExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   assert(targetExpr);
-  static_cast<CallIndirect*>(expression)->target = (Expression*)targetExpr;
+  static_cast<CallIndirect*>(expression)->target = static_cast<Expression*>(targetExpr);
 }
 const char* BinaryenCallIndirectGetTable(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   return static_cast<CallIndirect*>(expression)->table.str.data();
 }
 void BinaryenCallIndirectSetTable(BinaryenExpressionRef expr,
                                   const char* table) {
   Name name(table);
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
 
   assert(expression->is<CallIndirect>());
   static_cast<CallIndirect*>(expression)->table = name;
 }
 BinaryenIndex BinaryenCallIndirectGetNumOperands(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   return static_cast<CallIndirect*>(expression)->operands.size();
 }
 BinaryenExpressionRef
 BinaryenCallIndirectGetOperandAt(BinaryenExpressionRef expr,
                                  BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   assert(index < static_cast<CallIndirect*>(expression)->operands.size());
   return static_cast<CallIndirect*>(expression)->operands[index];
@@ -2387,52 +2387,52 @@
 void BinaryenCallIndirectSetOperandAt(BinaryenExpressionRef expr,
                                       BinaryenIndex index,
                                       BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   assert(index < static_cast<CallIndirect*>(expression)->operands.size());
   assert(operandExpr);
   static_cast<CallIndirect*>(expression)->operands[index] =
-    (Expression*)operandExpr;
+    static_cast<Expression*>(operandExpr);
 }
 BinaryenIndex
 BinaryenCallIndirectAppendOperand(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   assert(operandExpr);
   auto& list = static_cast<CallIndirect*>(expression)->operands;
   auto index = list.size();
-  list.push_back((Expression*)operandExpr);
+  list.push_back(static_cast<Expression*>(operandExpr));
   return index;
 }
 void BinaryenCallIndirectInsertOperandAt(BinaryenExpressionRef expr,
                                          BinaryenIndex index,
                                          BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   assert(operandExpr);
   static_cast<CallIndirect*>(expression)
-    ->operands.insertAt(index, (Expression*)operandExpr);
+    ->operands.insertAt(index, static_cast<Expression*>(operandExpr));
 }
 BinaryenExpressionRef
 BinaryenCallIndirectRemoveOperandAt(BinaryenExpressionRef expr,
                                     BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   return static_cast<CallIndirect*>(expression)->operands.removeAt(index);
 }
 bool BinaryenCallIndirectIsReturn(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   return static_cast<CallIndirect*>(expression)->isReturn;
 }
 void BinaryenCallIndirectSetReturn(BinaryenExpressionRef expr, bool isReturn) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   static_cast<CallIndirect*>(expression)->isReturn = isReturn != 0;
 }
 BinaryenType BinaryenCallIndirectGetParams(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   return static_cast<CallIndirect*>(expression)
     ->heapType.getSignature()
@@ -2440,12 +2440,12 @@
 }
 void BinaryenCallIndirectSetParams(BinaryenExpressionRef expr,
                                    BinaryenType params) {
-  auto* call = ((Expression*)expr)->cast<CallIndirect>();
+  auto* call = (static_cast<Expression*>(expr))->cast<CallIndirect>();
   call->heapType =
     Signature(Type(params), call->heapType.getSignature().results);
 }
 BinaryenType BinaryenCallIndirectGetResults(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallIndirect>());
   return static_cast<CallIndirect*>(expression)
     ->heapType.getSignature()
@@ -2453,223 +2453,223 @@
 }
 void BinaryenCallIndirectSetResults(BinaryenExpressionRef expr,
                                     BinaryenType results) {
-  auto* call = ((Expression*)expr)->cast<CallIndirect>();
+  auto* call = (static_cast<Expression*>(expr))->cast<CallIndirect>();
   call->heapType =
     Signature(call->heapType.getSignature().params, Type(results));
 }
 // LocalGet
 BinaryenIndex BinaryenLocalGetGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<LocalGet>());
   return static_cast<LocalGet*>(expression)->index;
 }
 void BinaryenLocalGetSetIndex(BinaryenExpressionRef expr, BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<LocalGet>());
   static_cast<LocalGet*>(expression)->index = index;
 }
 // LocalSet
 bool BinaryenLocalSetIsTee(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<LocalSet>());
   return static_cast<LocalSet*>(expression)->isTee();
   // has no setter
 }
 BinaryenIndex BinaryenLocalSetGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<LocalSet>());
   return static_cast<LocalSet*>(expression)->index;
 }
 void BinaryenLocalSetSetIndex(BinaryenExpressionRef expr, BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<LocalSet>());
   static_cast<LocalSet*>(expression)->index = index;
 }
 BinaryenExpressionRef BinaryenLocalSetGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<LocalSet>());
   return static_cast<LocalSet*>(expression)->value;
 }
 void BinaryenLocalSetSetValue(BinaryenExpressionRef expr,
                               BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<LocalSet>());
   assert(valueExpr);
-  static_cast<LocalSet*>(expression)->value = (Expression*)valueExpr;
+  static_cast<LocalSet*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // GlobalGet
 const char* BinaryenGlobalGetGetName(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<GlobalGet>());
   return static_cast<GlobalGet*>(expression)->name.str.data();
 }
 void BinaryenGlobalGetSetName(BinaryenExpressionRef expr, const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<GlobalGet>());
   assert(name);
   static_cast<GlobalGet*>(expression)->name = name;
 }
 // GlobalSet
 const char* BinaryenGlobalSetGetName(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<GlobalSet>());
   return static_cast<GlobalSet*>(expression)->name.str.data();
 }
 void BinaryenGlobalSetSetName(BinaryenExpressionRef expr, const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<GlobalSet>());
   assert(name);
   static_cast<GlobalSet*>(expression)->name = name;
 }
 BinaryenExpressionRef BinaryenGlobalSetGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<GlobalSet>());
   return static_cast<GlobalSet*>(expression)->value;
 }
 void BinaryenGlobalSetSetValue(BinaryenExpressionRef expr,
                                BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<GlobalSet>());
   assert(valueExpr);
-  static_cast<GlobalSet*>(expression)->value = (Expression*)valueExpr;
+  static_cast<GlobalSet*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // TableGet
 const char* BinaryenTableGetGetTable(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGet>());
   return static_cast<TableGet*>(expression)->table.str.data();
 }
 void BinaryenTableGetSetTable(BinaryenExpressionRef expr, const char* table) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGet>());
   assert(table);
   static_cast<TableGet*>(expression)->table = table;
 }
 BinaryenExpressionRef BinaryenTableGetGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGet>());
   return static_cast<TableGet*>(expression)->index;
 }
 void BinaryenTableGetSetIndex(BinaryenExpressionRef expr,
                               BinaryenExpressionRef indexExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGet>());
   assert(indexExpr);
-  static_cast<TableGet*>(expression)->index = (Expression*)indexExpr;
+  static_cast<TableGet*>(expression)->index = static_cast<Expression*>(indexExpr);
 }
 // TableSet
 const char* BinaryenTableSetGetTable(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableSet>());
   return static_cast<TableSet*>(expression)->table.str.data();
 }
 void BinaryenTableSetSetTable(BinaryenExpressionRef expr, const char* table) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableSet>());
   assert(table);
   static_cast<TableSet*>(expression)->table = table;
 }
 BinaryenExpressionRef BinaryenTableSetGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableSet>());
   return static_cast<TableSet*>(expression)->index;
 }
 void BinaryenTableSetSetIndex(BinaryenExpressionRef expr,
                               BinaryenExpressionRef indexExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableSet>());
   assert(indexExpr);
-  static_cast<TableSet*>(expression)->index = (Expression*)indexExpr;
+  static_cast<TableSet*>(expression)->index = static_cast<Expression*>(indexExpr);
 }
 BinaryenExpressionRef BinaryenTableSetGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableSet>());
   return static_cast<TableSet*>(expression)->value;
 }
 void BinaryenTableSetSetValue(BinaryenExpressionRef expr,
                               BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableSet>());
   assert(valueExpr);
-  static_cast<TableSet*>(expression)->value = (Expression*)valueExpr;
+  static_cast<TableSet*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // TableSize
 const char* BinaryenTableSizeGetTable(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableSize>());
   return static_cast<TableSize*>(expression)->table.str.data();
 }
 void BinaryenTableSizeSetTable(BinaryenExpressionRef expr, const char* table) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableSize>());
   assert(table);
   static_cast<TableSize*>(expression)->table = table;
 }
 // TableGrow
 const char* BinaryenTableGrowGetTable(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGrow>());
   return static_cast<TableGrow*>(expression)->table.str.data();
 }
 void BinaryenTableGrowSetTable(BinaryenExpressionRef expr, const char* table) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGrow>());
   assert(table);
   static_cast<TableGrow*>(expression)->table = table;
 }
 BinaryenExpressionRef BinaryenTableGrowGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGrow>());
   return static_cast<TableGrow*>(expression)->value;
 }
 void BinaryenTableGrowSetValue(BinaryenExpressionRef expr,
                                BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGrow>());
   assert(valueExpr);
-  static_cast<TableGrow*>(expression)->value = (Expression*)valueExpr;
+  static_cast<TableGrow*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 BinaryenExpressionRef BinaryenTableGrowGetDelta(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGrow>());
   return static_cast<TableGrow*>(expression)->delta;
 }
 void BinaryenTableGrowSetDelta(BinaryenExpressionRef expr,
                                BinaryenExpressionRef deltaExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TableGrow>());
   assert(deltaExpr);
-  static_cast<TableGrow*>(expression)->delta = (Expression*)deltaExpr;
+  static_cast<TableGrow*>(expression)->delta = static_cast<Expression*>(deltaExpr);
 }
 // MemoryGrow
 BinaryenExpressionRef BinaryenMemoryGrowGetDelta(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryGrow>());
   return static_cast<MemoryGrow*>(expression)->delta;
 }
 void BinaryenMemoryGrowSetDelta(BinaryenExpressionRef expr,
                                 BinaryenExpressionRef deltaExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryGrow>());
   assert(deltaExpr);
-  static_cast<MemoryGrow*>(expression)->delta = (Expression*)deltaExpr;
+  static_cast<MemoryGrow*>(expression)->delta = static_cast<Expression*>(deltaExpr);
 }
 // Load
 bool BinaryenLoadIsAtomic(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   return static_cast<Load*>(expression)->isAtomic();
 }
 
 void BinaryenLoadSetAtomic(BinaryenExpressionRef expr, bool isAtomic) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   static_cast<Load*>(expression)->order =
     isAtomic ? MemoryOrder::SeqCst : MemoryOrder::Unordered;
 }
 
 BinaryenMemoryOrder BinaryenLoadGetMemoryOrder(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   return static_cast<BinaryenMemoryOrder>(
     static_cast<Load*>(expression)->order);
@@ -2677,78 +2677,78 @@
 
 void BinaryenLoadSetMemoryOrder(BinaryenExpressionRef expr,
                                 BinaryenMemoryOrder order) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   static_cast<Load*>(expression)->order = static_cast<MemoryOrder>(order);
 }
 
 bool BinaryenLoadIsSigned(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   return static_cast<Load*>(expression)->signed_;
 }
 void BinaryenLoadSetSigned(BinaryenExpressionRef expr, bool isSigned) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   static_cast<Load*>(expression)->signed_ = isSigned != 0;
 }
 uint32_t BinaryenLoadGetBytes(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   return static_cast<Load*>(expression)->bytes;
 }
 void BinaryenLoadSetBytes(BinaryenExpressionRef expr, uint32_t bytes) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   static_cast<Load*>(expression)->bytes = bytes;
 }
 uint32_t BinaryenLoadGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   return static_cast<Load*>(expression)->offset;
 }
 void BinaryenLoadSetOffset(BinaryenExpressionRef expr, uint32_t offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   static_cast<Load*>(expression)->offset = offset;
 }
 uint32_t BinaryenLoadGetAlign(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   return static_cast<Load*>(expression)->align;
 }
 void BinaryenLoadSetAlign(BinaryenExpressionRef expr, uint32_t align) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   static_cast<Load*>(expression)->align = align;
 }
 BinaryenExpressionRef BinaryenLoadGetPtr(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   return static_cast<Load*>(expression)->ptr;
 }
 void BinaryenLoadSetPtr(BinaryenExpressionRef expr,
                         BinaryenExpressionRef ptrExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Load>());
   assert(ptrExpr);
-  static_cast<Load*>(expression)->ptr = (Expression*)ptrExpr;
+  static_cast<Load*>(expression)->ptr = static_cast<Expression*>(ptrExpr);
 }
 // Store
 bool BinaryenStoreIsAtomic(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   return static_cast<Store*>(expression)->isAtomic();
 }
 void BinaryenStoreSetAtomic(BinaryenExpressionRef expr, bool isAtomic) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   static_cast<Store*>(expression)->order =
     isAtomic ? MemoryOrder::SeqCst : MemoryOrder::Unordered;
 }
 
 BinaryenMemoryOrder BinaryenStoreGetMemoryOrder(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   return static_cast<BinaryenMemoryOrder>(
     static_cast<Store*>(expression)->order);
@@ -2756,309 +2756,309 @@
 
 void BinaryenStoreSetMemoryOrder(BinaryenExpressionRef expr,
                                  BinaryenMemoryOrder order) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   static_cast<Store*>(expression)->order = static_cast<MemoryOrder>(order);
 }
 
 uint32_t BinaryenStoreGetBytes(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   return static_cast<Store*>(expression)->bytes;
 }
 void BinaryenStoreSetBytes(BinaryenExpressionRef expr, uint32_t bytes) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   static_cast<Store*>(expression)->bytes = bytes;
 }
 uint32_t BinaryenStoreGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   return static_cast<Store*>(expression)->offset;
 }
 void BinaryenStoreSetOffset(BinaryenExpressionRef expr, uint32_t offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   static_cast<Store*>(expression)->offset = offset;
 }
 uint32_t BinaryenStoreGetAlign(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   return static_cast<Store*>(expression)->align;
 }
 void BinaryenStoreSetAlign(BinaryenExpressionRef expr, uint32_t align) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   static_cast<Store*>(expression)->align = align;
 }
 BinaryenExpressionRef BinaryenStoreGetPtr(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   return static_cast<Store*>(expression)->ptr;
 }
 void BinaryenStoreSetPtr(BinaryenExpressionRef expr,
                          BinaryenExpressionRef ptrExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   assert(ptrExpr);
-  static_cast<Store*>(expression)->ptr = (Expression*)ptrExpr;
+  static_cast<Store*>(expression)->ptr = static_cast<Expression*>(ptrExpr);
 }
 BinaryenExpressionRef BinaryenStoreGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   return static_cast<Store*>(expression)->value;
 }
 void BinaryenStoreSetValue(BinaryenExpressionRef expr,
                            BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   assert(valueExpr);
-  static_cast<Store*>(expression)->value = (Expression*)valueExpr;
+  static_cast<Store*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 BinaryenType BinaryenStoreGetValueType(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   return static_cast<Store*>(expression)->valueType.getID();
 }
 void BinaryenStoreSetValueType(BinaryenExpressionRef expr,
                                BinaryenType valueType) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Store>());
   static_cast<Store*>(expression)->valueType = Type(valueType);
 }
 // Const
 int32_t BinaryenConstGetValueI32(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   return static_cast<Const*>(expression)->value.geti32();
 }
 void BinaryenConstSetValueI32(BinaryenExpressionRef expr, int32_t value) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   static_cast<Const*>(expression)->value = Literal(value);
 }
 int64_t BinaryenConstGetValueI64(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   return static_cast<Const*>(expression)->value.geti64();
 }
 void BinaryenConstSetValueI64(BinaryenExpressionRef expr, int64_t value) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   static_cast<Const*>(expression)->value = Literal(value);
 }
 float BinaryenConstGetValueF32(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   return static_cast<Const*>(expression)->value.getf32();
 }
 void BinaryenConstSetValueF32(BinaryenExpressionRef expr, float value) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   static_cast<Const*>(expression)->value = Literal(value);
 }
 double BinaryenConstGetValueF64(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   return static_cast<Const*>(expression)->value.getf64();
 }
 void BinaryenConstSetValueF64(BinaryenExpressionRef expr, double value) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   static_cast<Const*>(expression)->value = Literal(value);
 }
 void BinaryenConstGetValueV128(BinaryenExpressionRef expr, uint8_t* out) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   memcpy(out, static_cast<Const*>(expression)->value.getv128().data(), 16);
 }
 void BinaryenConstSetValueV128(BinaryenExpressionRef expr,
                                const uint8_t value[16]) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Const>());
   assert(value); // nullptr would be wrong
   static_cast<Const*>(expression)->value = Literal(value);
 }
 // Unary
 BinaryenOp BinaryenUnaryGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Unary>());
   return static_cast<Unary*>(expression)->op;
 }
 void BinaryenUnarySetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Unary>());
   static_cast<Unary*>(expression)->op = UnaryOp(op);
 }
 BinaryenExpressionRef BinaryenUnaryGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Unary>());
   return static_cast<Unary*>(expression)->value;
 }
 void BinaryenUnarySetValue(BinaryenExpressionRef expr,
                            BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Unary>());
   assert(valueExpr);
-  static_cast<Unary*>(expression)->value = (Expression*)valueExpr;
+  static_cast<Unary*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // Binary
 BinaryenOp BinaryenBinaryGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Binary>());
   return static_cast<Binary*>(expression)->op;
 }
 void BinaryenBinarySetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Binary>());
   static_cast<Binary*>(expression)->op = BinaryOp(op);
 }
 BinaryenExpressionRef BinaryenBinaryGetLeft(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Binary>());
   return static_cast<Binary*>(expression)->left;
 }
 void BinaryenBinarySetLeft(BinaryenExpressionRef expr,
                            BinaryenExpressionRef leftExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Binary>());
   assert(leftExpr);
-  static_cast<Binary*>(expression)->left = (Expression*)leftExpr;
+  static_cast<Binary*>(expression)->left = static_cast<Expression*>(leftExpr);
 }
 BinaryenExpressionRef BinaryenBinaryGetRight(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Binary>());
   return static_cast<Binary*>(expression)->right;
 }
 void BinaryenBinarySetRight(BinaryenExpressionRef expr,
                             BinaryenExpressionRef rightExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Binary>());
   assert(rightExpr);
-  static_cast<Binary*>(expression)->right = (Expression*)rightExpr;
+  static_cast<Binary*>(expression)->right = static_cast<Expression*>(rightExpr);
 }
 // Select
 BinaryenExpressionRef BinaryenSelectGetIfTrue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Select>());
   return static_cast<Select*>(expression)->ifTrue;
 }
 void BinaryenSelectSetIfTrue(BinaryenExpressionRef expr,
                              BinaryenExpressionRef ifTrueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Select>());
   assert(ifTrueExpr);
-  static_cast<Select*>(expression)->ifTrue = (Expression*)ifTrueExpr;
+  static_cast<Select*>(expression)->ifTrue = static_cast<Expression*>(ifTrueExpr);
 }
 BinaryenExpressionRef BinaryenSelectGetIfFalse(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Select>());
   return static_cast<Select*>(expression)->ifFalse;
 }
 void BinaryenSelectSetIfFalse(BinaryenExpressionRef expr,
                               BinaryenExpressionRef ifFalseExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Select>());
   assert(ifFalseExpr);
-  static_cast<Select*>(expression)->ifFalse = (Expression*)ifFalseExpr;
+  static_cast<Select*>(expression)->ifFalse = static_cast<Expression*>(ifFalseExpr);
 }
 BinaryenExpressionRef BinaryenSelectGetCondition(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Select>());
   return static_cast<Select*>(expression)->condition;
 }
 void BinaryenSelectSetCondition(BinaryenExpressionRef expr,
                                 BinaryenExpressionRef condExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Select>());
   assert(condExpr);
-  static_cast<Select*>(expression)->condition = (Expression*)condExpr;
+  static_cast<Select*>(expression)->condition = static_cast<Expression*>(condExpr);
 }
 // Drop
 BinaryenExpressionRef BinaryenDropGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Drop>());
   return static_cast<Drop*>(expression)->value;
 }
 void BinaryenDropSetValue(BinaryenExpressionRef expr,
                           BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Drop>());
   assert(valueExpr);
-  static_cast<Drop*>(expression)->value = (Expression*)valueExpr;
+  static_cast<Drop*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // Return
 BinaryenExpressionRef BinaryenReturnGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Return>());
   return static_cast<Return*>(expression)->value;
 }
 void BinaryenReturnSetValue(BinaryenExpressionRef expr,
                             BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Return>());
   // may be null
-  static_cast<Return*>(expression)->value = (Expression*)valueExpr;
+  static_cast<Return*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // AtomicRMW
 BinaryenOp BinaryenAtomicRMWGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   return static_cast<AtomicRMW*>(expression)->op;
 }
 void BinaryenAtomicRMWSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   static_cast<AtomicRMW*>(expression)->op = AtomicRMWOp(op);
 }
 uint32_t BinaryenAtomicRMWGetBytes(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   return static_cast<AtomicRMW*>(expression)->bytes;
 }
 void BinaryenAtomicRMWSetBytes(BinaryenExpressionRef expr, uint32_t bytes) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   static_cast<AtomicRMW*>(expression)->bytes = bytes;
 }
 uint32_t BinaryenAtomicRMWGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   return static_cast<AtomicRMW*>(expression)->offset;
 }
 void BinaryenAtomicRMWSetOffset(BinaryenExpressionRef expr, uint32_t offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   static_cast<AtomicRMW*>(expression)->offset = offset;
 }
 BinaryenExpressionRef BinaryenAtomicRMWGetPtr(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   return static_cast<AtomicRMW*>(expression)->ptr;
 }
 void BinaryenAtomicRMWSetPtr(BinaryenExpressionRef expr,
                              BinaryenExpressionRef ptrExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   assert(ptrExpr);
-  static_cast<AtomicRMW*>(expression)->ptr = (Expression*)ptrExpr;
+  static_cast<AtomicRMW*>(expression)->ptr = static_cast<Expression*>(ptrExpr);
 }
 BinaryenExpressionRef BinaryenAtomicRMWGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   return static_cast<AtomicRMW*>(expression)->value;
 }
 void BinaryenAtomicRMWSetValue(BinaryenExpressionRef expr,
                                BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   assert(valueExpr);
-  static_cast<AtomicRMW*>(expression)->value = (Expression*)valueExpr;
+  static_cast<AtomicRMW*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 
 BinaryenMemoryOrder
 BinaryenAtomicRMWGetMemoryOrder(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   return static_cast<BinaryenMemoryOrder>(
     static_cast<AtomicRMW*>(expression)->order);
@@ -3066,75 +3066,75 @@
 
 void BinaryenAtomicRMWSetMemoryOrder(BinaryenExpressionRef expr,
                                      BinaryenMemoryOrder order) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicRMW>());
   static_cast<AtomicRMW*>(expression)->order = static_cast<MemoryOrder>(order);
 }
 // AtomicCmpxchg
 uint32_t BinaryenAtomicCmpxchgGetBytes(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   return static_cast<AtomicCmpxchg*>(expression)->bytes;
 }
 void BinaryenAtomicCmpxchgSetBytes(BinaryenExpressionRef expr, uint32_t bytes) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   static_cast<AtomicCmpxchg*>(expression)->bytes = bytes;
 }
 uint32_t BinaryenAtomicCmpxchgGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   return static_cast<AtomicCmpxchg*>(expression)->offset;
 }
 void BinaryenAtomicCmpxchgSetOffset(BinaryenExpressionRef expr,
                                     uint32_t offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   static_cast<AtomicCmpxchg*>(expression)->offset = offset;
 }
 BinaryenExpressionRef BinaryenAtomicCmpxchgGetPtr(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   return static_cast<AtomicCmpxchg*>(expression)->ptr;
 }
 void BinaryenAtomicCmpxchgSetPtr(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef ptrExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   assert(ptrExpr);
-  static_cast<AtomicCmpxchg*>(expression)->ptr = (Expression*)ptrExpr;
+  static_cast<AtomicCmpxchg*>(expression)->ptr = static_cast<Expression*>(ptrExpr);
 }
 BinaryenExpressionRef
 BinaryenAtomicCmpxchgGetExpected(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   return static_cast<AtomicCmpxchg*>(expression)->expected;
 }
 void BinaryenAtomicCmpxchgSetExpected(BinaryenExpressionRef expr,
                                       BinaryenExpressionRef expectedExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   assert(expectedExpr);
-  static_cast<AtomicCmpxchg*>(expression)->expected = (Expression*)expectedExpr;
+  static_cast<AtomicCmpxchg*>(expression)->expected = static_cast<Expression*>(expectedExpr);
 }
 BinaryenExpressionRef
 BinaryenAtomicCmpxchgGetReplacement(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   return static_cast<AtomicCmpxchg*>(expression)->replacement;
 }
 void BinaryenAtomicCmpxchgSetReplacement(
   BinaryenExpressionRef expr, BinaryenExpressionRef replacementExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   assert(replacementExpr);
   static_cast<AtomicCmpxchg*>(expression)->replacement =
-    (Expression*)replacementExpr;
+    static_cast<Expression*>(replacementExpr);
 }
 
 BinaryenMemoryOrder
 BinaryenAtomicCmpxchgGetMemoryOrder(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   return static_cast<BinaryenMemoryOrder>(
     static_cast<AtomicCmpxchg*>(expression)->order);
@@ -3142,210 +3142,210 @@
 
 void BinaryenAtomicCmpxchgSetMemoryOrder(BinaryenExpressionRef expr,
                                          BinaryenMemoryOrder order) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicCmpxchg>());
   static_cast<AtomicCmpxchg*>(expression)->order =
     static_cast<MemoryOrder>(order);
 }
 // AtomicWait
 BinaryenExpressionRef BinaryenAtomicWaitGetPtr(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicWait>());
   return static_cast<AtomicWait*>(expression)->ptr;
 }
 void BinaryenAtomicWaitSetPtr(BinaryenExpressionRef expr,
                               BinaryenExpressionRef ptrExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicWait>());
   assert(ptrExpr);
-  static_cast<AtomicWait*>(expression)->ptr = (Expression*)ptrExpr;
+  static_cast<AtomicWait*>(expression)->ptr = static_cast<Expression*>(ptrExpr);
 }
 BinaryenExpressionRef
 BinaryenAtomicWaitGetExpected(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicWait>());
   return static_cast<AtomicWait*>(expression)->expected;
 }
 void BinaryenAtomicWaitSetExpected(BinaryenExpressionRef expr,
                                    BinaryenExpressionRef expectedExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicWait>());
   assert(expectedExpr);
-  static_cast<AtomicWait*>(expression)->expected = (Expression*)expectedExpr;
+  static_cast<AtomicWait*>(expression)->expected = static_cast<Expression*>(expectedExpr);
 }
 BinaryenExpressionRef BinaryenAtomicWaitGetTimeout(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicWait>());
   return static_cast<AtomicWait*>(expression)->timeout;
 }
 void BinaryenAtomicWaitSetTimeout(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef timeoutExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicWait>());
   assert(timeoutExpr);
-  static_cast<AtomicWait*>(expression)->timeout = (Expression*)timeoutExpr;
+  static_cast<AtomicWait*>(expression)->timeout = static_cast<Expression*>(timeoutExpr);
 }
 BinaryenType BinaryenAtomicWaitGetExpectedType(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicWait>());
   return static_cast<AtomicWait*>(expression)->expectedType.getID();
 }
 void BinaryenAtomicWaitSetExpectedType(BinaryenExpressionRef expr,
                                        BinaryenType expectedType) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicWait>());
   static_cast<AtomicWait*>(expression)->expectedType = Type(expectedType);
 }
 // AtomicNotify
 BinaryenExpressionRef BinaryenAtomicNotifyGetPtr(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicNotify>());
   return static_cast<AtomicNotify*>(expression)->ptr;
 }
 void BinaryenAtomicNotifySetPtr(BinaryenExpressionRef expr,
                                 BinaryenExpressionRef ptrExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicNotify>());
   assert(ptrExpr);
-  static_cast<AtomicNotify*>(expression)->ptr = (Expression*)ptrExpr;
+  static_cast<AtomicNotify*>(expression)->ptr = static_cast<Expression*>(ptrExpr);
 }
 BinaryenExpressionRef
 BinaryenAtomicNotifyGetNotifyCount(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicNotify>());
   return static_cast<AtomicNotify*>(expression)->notifyCount;
 }
 void BinaryenAtomicNotifySetNotifyCount(BinaryenExpressionRef expr,
                                         BinaryenExpressionRef notifyCountExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicNotify>());
   assert(notifyCountExpr);
   static_cast<AtomicNotify*>(expression)->notifyCount =
-    (Expression*)notifyCountExpr;
+    static_cast<Expression*>(notifyCountExpr);
 }
 // AtomicFence
 uint8_t BinaryenAtomicFenceGetOrder(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicFence>());
   return static_cast<AtomicFence*>(expression)->order;
 }
 void BinaryenAtomicFenceSetOrder(BinaryenExpressionRef expr, uint8_t order) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<AtomicFence>());
   static_cast<AtomicFence*>(expression)->order = order;
 }
 // SIMDExtract
 BinaryenOp BinaryenSIMDExtractGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDExtract>());
   return static_cast<SIMDExtract*>(expression)->op;
 }
 void BinaryenSIMDExtractSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDExtract>());
   static_cast<SIMDExtract*>(expression)->op = SIMDExtractOp(op);
 }
 BinaryenExpressionRef BinaryenSIMDExtractGetVec(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDExtract>());
   return static_cast<SIMDExtract*>(expression)->vec;
 }
 void BinaryenSIMDExtractSetVec(BinaryenExpressionRef expr,
                                BinaryenExpressionRef vecExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDExtract>());
   assert(vecExpr);
-  static_cast<SIMDExtract*>(expression)->vec = (Expression*)vecExpr;
+  static_cast<SIMDExtract*>(expression)->vec = static_cast<Expression*>(vecExpr);
 }
 uint8_t BinaryenSIMDExtractGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDExtract>());
   return static_cast<SIMDExtract*>(expression)->index;
 }
 void BinaryenSIMDExtractSetIndex(BinaryenExpressionRef expr, uint8_t index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDExtract>());
   static_cast<SIMDExtract*>(expression)->index = index;
 }
 // SIMDReplace
 BinaryenOp BinaryenSIMDReplaceGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDReplace>());
   return static_cast<SIMDReplace*>(expression)->op;
 }
 void BinaryenSIMDReplaceSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDReplace>());
   static_cast<SIMDReplace*>(expression)->op = SIMDReplaceOp(op);
 }
 BinaryenExpressionRef BinaryenSIMDReplaceGetVec(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDReplace>());
   return static_cast<SIMDReplace*>(expression)->vec;
 }
 void BinaryenSIMDReplaceSetVec(BinaryenExpressionRef expr,
                                BinaryenExpressionRef vecExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDReplace>());
   assert(vecExpr);
-  static_cast<SIMDReplace*>(expression)->vec = (Expression*)vecExpr;
+  static_cast<SIMDReplace*>(expression)->vec = static_cast<Expression*>(vecExpr);
 }
 uint8_t BinaryenSIMDReplaceGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDReplace>());
   return static_cast<SIMDReplace*>(expression)->index;
 }
 void BinaryenSIMDReplaceSetIndex(BinaryenExpressionRef expr, uint8_t index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDReplace>());
   static_cast<SIMDReplace*>(expression)->index = index;
 }
 BinaryenExpressionRef BinaryenSIMDReplaceGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDReplace>());
   return static_cast<SIMDReplace*>(expression)->value;
 }
 void BinaryenSIMDReplaceSetValue(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDReplace>());
   assert(valueExpr);
-  static_cast<SIMDReplace*>(expression)->value = (Expression*)valueExpr;
+  static_cast<SIMDReplace*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // SIMDShuffle
 BinaryenExpressionRef BinaryenSIMDShuffleGetLeft(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShuffle>());
   return static_cast<SIMDShuffle*>(expression)->left;
 }
 void BinaryenSIMDShuffleSetLeft(BinaryenExpressionRef expr,
                                 BinaryenExpressionRef leftExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShuffle>());
   assert(leftExpr);
-  static_cast<SIMDShuffle*>(expression)->left = (Expression*)leftExpr;
+  static_cast<SIMDShuffle*>(expression)->left = static_cast<Expression*>(leftExpr);
 }
 BinaryenExpressionRef BinaryenSIMDShuffleGetRight(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShuffle>());
   return static_cast<SIMDShuffle*>(expression)->right;
 }
 void BinaryenSIMDShuffleSetRight(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef rightExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShuffle>());
   assert(rightExpr);
-  static_cast<SIMDShuffle*>(expression)->right = (Expression*)rightExpr;
+  static_cast<SIMDShuffle*>(expression)->right = static_cast<Expression*>(rightExpr);
 }
 void BinaryenSIMDShuffleGetMask(BinaryenExpressionRef expr, uint8_t* mask) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShuffle>());
   assert(mask); // nullptr would be wrong
   memcpy(mask, static_cast<SIMDShuffle*>(expression)->mask.data(), 16);
 }
 void BinaryenSIMDShuffleSetMask(BinaryenExpressionRef expr,
                                 const uint8_t mask_[16]) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShuffle>());
   assert(mask_); // nullptr would be wrong
   auto& mask = static_cast<SIMDShuffle*>(expression)->mask;
@@ -3353,444 +3353,444 @@
 }
 // SIMDTernary
 BinaryenOp BinaryenSIMDTernaryGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDTernary>());
   return static_cast<SIMDTernary*>(expression)->op;
 }
 void BinaryenSIMDTernarySetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDTernary>());
   static_cast<SIMDTernary*>(expression)->op = SIMDTernaryOp(op);
 }
 BinaryenExpressionRef BinaryenSIMDTernaryGetA(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDTernary>());
   return static_cast<SIMDTernary*>(expression)->a;
 }
 void BinaryenSIMDTernarySetA(BinaryenExpressionRef expr,
                              BinaryenExpressionRef aExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDTernary>());
   assert(aExpr);
-  static_cast<SIMDTernary*>(expression)->a = (Expression*)aExpr;
+  static_cast<SIMDTernary*>(expression)->a = static_cast<Expression*>(aExpr);
 }
 BinaryenExpressionRef BinaryenSIMDTernaryGetB(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDTernary>());
   return static_cast<SIMDTernary*>(expression)->b;
 }
 void BinaryenSIMDTernarySetB(BinaryenExpressionRef expr,
                              BinaryenExpressionRef bExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDTernary>());
   assert(bExpr);
-  static_cast<SIMDTernary*>(expression)->b = (Expression*)bExpr;
+  static_cast<SIMDTernary*>(expression)->b = static_cast<Expression*>(bExpr);
 }
 BinaryenExpressionRef BinaryenSIMDTernaryGetC(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDTernary>());
   return static_cast<SIMDTernary*>(expression)->c;
 }
 void BinaryenSIMDTernarySetC(BinaryenExpressionRef expr,
                              BinaryenExpressionRef cExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDTernary>());
   assert(cExpr);
-  static_cast<SIMDTernary*>(expression)->c = (Expression*)cExpr;
+  static_cast<SIMDTernary*>(expression)->c = static_cast<Expression*>(cExpr);
 }
 // SIMDShift
 BinaryenOp BinaryenSIMDShiftGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShift>());
   return static_cast<SIMDShift*>(expression)->op;
 }
 void BinaryenSIMDShiftSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShift>());
   static_cast<SIMDShift*>(expression)->op = SIMDShiftOp(op);
 }
 BinaryenExpressionRef BinaryenSIMDShiftGetVec(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShift>());
   return static_cast<SIMDShift*>(expression)->vec;
 }
 void BinaryenSIMDShiftSetVec(BinaryenExpressionRef expr,
                              BinaryenExpressionRef vecExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShift>());
   assert(vecExpr);
-  static_cast<SIMDShift*>(expression)->vec = (Expression*)vecExpr;
+  static_cast<SIMDShift*>(expression)->vec = static_cast<Expression*>(vecExpr);
 }
 BinaryenExpressionRef BinaryenSIMDShiftGetShift(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShift>());
   return static_cast<SIMDShift*>(expression)->shift;
 }
 void BinaryenSIMDShiftSetShift(BinaryenExpressionRef expr,
                                BinaryenExpressionRef shiftExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDShift>());
   assert(shiftExpr);
-  static_cast<SIMDShift*>(expression)->shift = (Expression*)shiftExpr;
+  static_cast<SIMDShift*>(expression)->shift = static_cast<Expression*>(shiftExpr);
 }
 // SIMDLoad
 BinaryenOp BinaryenSIMDLoadGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoad>());
   return static_cast<SIMDLoad*>(expression)->op;
 }
 void BinaryenSIMDLoadSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoad>());
   static_cast<SIMDLoad*>(expression)->op = SIMDLoadOp(op);
 }
 uint32_t BinaryenSIMDLoadGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoad>());
   return static_cast<SIMDLoad*>(expression)->offset;
 }
 void BinaryenSIMDLoadSetOffset(BinaryenExpressionRef expr, uint32_t offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoad>());
   static_cast<SIMDLoad*>(expression)->offset = offset;
 }
 uint32_t BinaryenSIMDLoadGetAlign(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoad>());
   return static_cast<SIMDLoad*>(expression)->align;
 }
 void BinaryenSIMDLoadSetAlign(BinaryenExpressionRef expr, uint32_t align) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoad>());
   static_cast<SIMDLoad*>(expression)->align = align;
 }
 BinaryenExpressionRef BinaryenSIMDLoadGetPtr(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoad>());
   return static_cast<SIMDLoad*>(expression)->ptr;
 }
 void BinaryenSIMDLoadSetPtr(BinaryenExpressionRef expr,
                             BinaryenExpressionRef ptrExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoad>());
   assert(ptrExpr);
-  static_cast<SIMDLoad*>(expression)->ptr = (Expression*)ptrExpr;
+  static_cast<SIMDLoad*>(expression)->ptr = static_cast<Expression*>(ptrExpr);
 }
 // SIMDLoadStoreLane
 BinaryenOp BinaryenSIMDLoadStoreLaneGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   return static_cast<SIMDLoadStoreLane*>(expression)->op;
 }
 void BinaryenSIMDLoadStoreLaneSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   static_cast<SIMDLoadStoreLane*>(expression)->op = SIMDLoadStoreLaneOp(op);
 }
 uint32_t BinaryenSIMDLoadStoreLaneGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   return static_cast<SIMDLoadStoreLane*>(expression)->offset;
 }
 void BinaryenSIMDLoadStoreLaneSetOffset(BinaryenExpressionRef expr,
                                         uint32_t offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   static_cast<SIMDLoadStoreLane*>(expression)->offset = offset;
 }
 uint32_t BinaryenSIMDLoadStoreLaneGetAlign(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   return static_cast<SIMDLoadStoreLane*>(expression)->align;
 }
 void BinaryenSIMDLoadStoreLaneSetAlign(BinaryenExpressionRef expr,
                                        uint32_t align) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   static_cast<SIMDLoadStoreLane*>(expression)->align = align;
 }
 uint8_t BinaryenSIMDLoadStoreLaneGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   return static_cast<SIMDLoadStoreLane*>(expression)->index;
 }
 void BinaryenSIMDLoadStoreLaneSetIndex(BinaryenExpressionRef expr,
                                        uint8_t index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   static_cast<SIMDLoadStoreLane*>(expression)->index = index;
 }
 BinaryenExpressionRef
 BinaryenSIMDLoadStoreLaneGetPtr(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   return static_cast<SIMDLoadStoreLane*>(expression)->ptr;
 }
 void BinaryenSIMDLoadStoreLaneSetPtr(BinaryenExpressionRef expr,
                                      BinaryenExpressionRef ptrExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   assert(ptrExpr);
-  static_cast<SIMDLoadStoreLane*>(expression)->ptr = (Expression*)ptrExpr;
+  static_cast<SIMDLoadStoreLane*>(expression)->ptr = static_cast<Expression*>(ptrExpr);
 }
 BinaryenExpressionRef
 BinaryenSIMDLoadStoreLaneGetVec(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   return static_cast<SIMDLoadStoreLane*>(expression)->vec;
 }
 void BinaryenSIMDLoadStoreLaneSetVec(BinaryenExpressionRef expr,
                                      BinaryenExpressionRef vecExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   assert(vecExpr);
-  static_cast<SIMDLoadStoreLane*>(expression)->vec = (Expression*)vecExpr;
+  static_cast<SIMDLoadStoreLane*>(expression)->vec = static_cast<Expression*>(vecExpr);
 }
 bool BinaryenSIMDLoadStoreLaneIsStore(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<SIMDLoadStoreLane>());
   return static_cast<SIMDLoadStoreLane*>(expression)->isStore();
 }
 // MemoryInit
 const char* BinaryenMemoryInitGetSegment(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryInit>());
   return static_cast<MemoryInit*>(expression)->segment.str.data();
 }
 void BinaryenMemoryInitSetSegment(BinaryenExpressionRef expr,
                                   const char* segment) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryInit>());
   static_cast<MemoryInit*>(expression)->segment = Name(segment);
 }
 BinaryenExpressionRef BinaryenMemoryInitGetDest(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryInit>());
   return static_cast<MemoryInit*>(expression)->dest;
 }
 void BinaryenMemoryInitSetDest(BinaryenExpressionRef expr,
                                BinaryenExpressionRef destExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryInit>());
   assert(destExpr);
-  static_cast<MemoryInit*>(expression)->dest = (Expression*)destExpr;
+  static_cast<MemoryInit*>(expression)->dest = static_cast<Expression*>(destExpr);
 }
 BinaryenExpressionRef BinaryenMemoryInitGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryInit>());
   return static_cast<MemoryInit*>(expression)->offset;
 }
 void BinaryenMemoryInitSetOffset(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef offsetExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryInit>());
   assert(offsetExpr);
-  static_cast<MemoryInit*>(expression)->offset = (Expression*)offsetExpr;
+  static_cast<MemoryInit*>(expression)->offset = static_cast<Expression*>(offsetExpr);
 }
 BinaryenExpressionRef BinaryenMemoryInitGetSize(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryInit>());
   return static_cast<MemoryInit*>(expression)->size;
 }
 void BinaryenMemoryInitSetSize(BinaryenExpressionRef expr,
                                BinaryenExpressionRef sizeExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryInit>());
   assert(sizeExpr);
-  static_cast<MemoryInit*>(expression)->size = (Expression*)sizeExpr;
+  static_cast<MemoryInit*>(expression)->size = static_cast<Expression*>(sizeExpr);
 }
 // DataDrop
 const char* BinaryenDataDropGetSegment(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<DataDrop>());
   return static_cast<DataDrop*>(expression)->segment.str.data();
 }
 void BinaryenDataDropSetSegment(BinaryenExpressionRef expr,
                                 const char* segment) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<DataDrop>());
   static_cast<DataDrop*>(expression)->segment = Name(segment);
 }
 // MemoryCopy
 BinaryenExpressionRef BinaryenMemoryCopyGetDest(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryCopy>());
   return static_cast<MemoryCopy*>(expression)->dest;
 }
 void BinaryenMemoryCopySetDest(BinaryenExpressionRef expr,
                                BinaryenExpressionRef destExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryCopy>());
   assert(destExpr);
-  static_cast<MemoryCopy*>(expression)->dest = (Expression*)destExpr;
+  static_cast<MemoryCopy*>(expression)->dest = static_cast<Expression*>(destExpr);
 }
 BinaryenExpressionRef BinaryenMemoryCopyGetSource(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryCopy>());
   return static_cast<MemoryCopy*>(expression)->source;
 }
 void BinaryenMemoryCopySetSource(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef sourceExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryCopy>());
   assert(sourceExpr);
-  static_cast<MemoryCopy*>(expression)->source = (Expression*)sourceExpr;
+  static_cast<MemoryCopy*>(expression)->source = static_cast<Expression*>(sourceExpr);
 }
 BinaryenExpressionRef BinaryenMemoryCopyGetSize(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryCopy>());
   return static_cast<MemoryCopy*>(expression)->size;
 }
 void BinaryenMemoryCopySetSize(BinaryenExpressionRef expr,
                                BinaryenExpressionRef sizeExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryCopy>());
   assert(sizeExpr);
-  static_cast<MemoryCopy*>(expression)->size = (Expression*)sizeExpr;
+  static_cast<MemoryCopy*>(expression)->size = static_cast<Expression*>(sizeExpr);
 }
 // MemoryFill
 BinaryenExpressionRef BinaryenMemoryFillGetDest(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryFill>());
   return static_cast<MemoryFill*>(expression)->dest;
 }
 void BinaryenMemoryFillSetDest(BinaryenExpressionRef expr,
                                BinaryenExpressionRef destExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryFill>());
   assert(destExpr);
-  static_cast<MemoryFill*>(expression)->dest = (Expression*)destExpr;
+  static_cast<MemoryFill*>(expression)->dest = static_cast<Expression*>(destExpr);
 }
 BinaryenExpressionRef BinaryenMemoryFillGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryFill>());
   return static_cast<MemoryFill*>(expression)->value;
 }
 void BinaryenMemoryFillSetValue(BinaryenExpressionRef expr,
                                 BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryFill>());
   assert(valueExpr);
-  static_cast<MemoryFill*>(expression)->value = (Expression*)valueExpr;
+  static_cast<MemoryFill*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 BinaryenExpressionRef BinaryenMemoryFillGetSize(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryFill>());
   return static_cast<MemoryFill*>(expression)->size;
 }
 void BinaryenMemoryFillSetSize(BinaryenExpressionRef expr,
                                BinaryenExpressionRef sizeExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<MemoryFill>());
   assert(sizeExpr);
-  static_cast<MemoryFill*>(expression)->size = (Expression*)sizeExpr;
+  static_cast<MemoryFill*>(expression)->size = static_cast<Expression*>(sizeExpr);
 }
 // RefIsNull
 BinaryenExpressionRef BinaryenRefIsNullGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefIsNull>());
   return static_cast<RefIsNull*>(expression)->value;
 }
 void BinaryenRefIsNullSetValue(BinaryenExpressionRef expr,
                                BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefIsNull>());
   assert(valueExpr);
-  static_cast<RefIsNull*>(expression)->value = (Expression*)valueExpr;
+  static_cast<RefIsNull*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // RefAs
 BinaryenOp BinaryenRefAsGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefAs>());
   return static_cast<RefAs*>(expression)->op;
 }
 void BinaryenRefAsSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefAs>());
   static_cast<RefAs*>(expression)->op = RefAsOp(op);
 }
 BinaryenExpressionRef BinaryenRefAsGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefAs>());
   return static_cast<RefAs*>(expression)->value;
 }
 void BinaryenRefAsSetValue(BinaryenExpressionRef expr,
                            BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefAs>());
   assert(valueExpr);
-  static_cast<RefAs*>(expression)->value = (Expression*)valueExpr;
+  static_cast<RefAs*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // RefFunc
 const char* BinaryenRefFuncGetFunc(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefFunc>());
   return static_cast<RefFunc*>(expression)->func.str.data();
 }
 void BinaryenRefFuncSetFunc(BinaryenExpressionRef expr, const char* funcName) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefFunc>());
   static_cast<RefFunc*>(expression)->func = funcName;
 }
 // RefEq
 BinaryenExpressionRef BinaryenRefEqGetLeft(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefEq>());
   return static_cast<RefEq*>(expression)->left;
 }
 void BinaryenRefEqSetLeft(BinaryenExpressionRef expr,
                           BinaryenExpressionRef left) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefEq>());
-  static_cast<RefEq*>(expression)->left = (Expression*)left;
+  static_cast<RefEq*>(expression)->left = static_cast<Expression*>(left);
 }
 BinaryenExpressionRef BinaryenRefEqGetRight(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefEq>());
   return static_cast<RefEq*>(expression)->right;
 }
 void BinaryenRefEqSetRight(BinaryenExpressionRef expr,
                            BinaryenExpressionRef right) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefEq>());
-  static_cast<RefEq*>(expression)->right = (Expression*)right;
+  static_cast<RefEq*>(expression)->right = static_cast<Expression*>(right);
 }
 // Try
 const char* BinaryenTryGetName(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   return static_cast<Try*>(expression)->name.str.data();
 }
 void BinaryenTrySetName(BinaryenExpressionRef expr, const char* name) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   static_cast<Try*>(expression)->name = name;
 }
 BinaryenExpressionRef BinaryenTryGetBody(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   return static_cast<Try*>(expression)->body;
 }
 void BinaryenTrySetBody(BinaryenExpressionRef expr,
                         BinaryenExpressionRef bodyExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   assert(bodyExpr);
-  static_cast<Try*>(expression)->body = (Expression*)bodyExpr;
+  static_cast<Try*>(expression)->body = static_cast<Expression*>(bodyExpr);
 }
 BinaryenIndex BinaryenTryGetNumCatchTags(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   return static_cast<Try*>(expression)->catchTags.size();
 }
 BinaryenIndex BinaryenTryGetNumCatchBodies(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   return static_cast<Try*>(expression)->catchBodies.size();
 }
 const char* BinaryenTryGetCatchTagAt(BinaryenExpressionRef expr,
                                      BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   assert(index < static_cast<Try*>(expression)->catchTags.size());
   return static_cast<Try*>(expression)->catchTags[index].str.data();
@@ -3798,7 +3798,7 @@
 void BinaryenTrySetCatchTagAt(BinaryenExpressionRef expr,
                               BinaryenIndex index,
                               const char* catchTag) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   assert(index < static_cast<Try*>(expression)->catchTags.size());
   assert(catchTag);
@@ -3806,7 +3806,7 @@
 }
 BinaryenIndex BinaryenTryAppendCatchTag(BinaryenExpressionRef expr,
                                         const char* catchTag) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   assert(catchTag);
   auto& list = static_cast<Try*>(expression)->catchTags;
@@ -3817,20 +3817,20 @@
 void BinaryenTryInsertCatchTagAt(BinaryenExpressionRef expr,
                                  BinaryenIndex index,
                                  const char* catchTag) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   assert(catchTag);
   static_cast<Try*>(expression)->catchTags.insertAt(index, catchTag);
 }
 const char* BinaryenTryRemoveCatchTagAt(BinaryenExpressionRef expr,
                                         BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   return static_cast<Try*>(expression)->catchTags.removeAt(index).str.data();
 }
 BinaryenExpressionRef BinaryenTryGetCatchBodyAt(BinaryenExpressionRef expr,
                                                 BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   assert(index < static_cast<Try*>(expression)->catchBodies.size());
   return static_cast<Try*>(expression)->catchBodies[index];
@@ -3838,77 +3838,77 @@
 void BinaryenTrySetCatchBodyAt(BinaryenExpressionRef expr,
                                BinaryenIndex index,
                                BinaryenExpressionRef catchExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   assert(index < static_cast<Try*>(expression)->catchBodies.size());
   assert(catchExpr);
-  static_cast<Try*>(expression)->catchBodies[index] = (Expression*)catchExpr;
+  static_cast<Try*>(expression)->catchBodies[index] = static_cast<Expression*>(catchExpr);
 }
 BinaryenIndex BinaryenTryAppendCatchBody(BinaryenExpressionRef expr,
                                          BinaryenExpressionRef catchExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   assert(catchExpr);
   auto& list = static_cast<Try*>(expression)->catchBodies;
   auto index = list.size();
-  list.push_back((Expression*)catchExpr);
+  list.push_back(static_cast<Expression*>(catchExpr));
   return index;
 }
 void BinaryenTryInsertCatchBodyAt(BinaryenExpressionRef expr,
                                   BinaryenIndex index,
                                   BinaryenExpressionRef catchExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   assert(catchExpr);
   static_cast<Try*>(expression)
-    ->catchBodies.insertAt(index, (Expression*)catchExpr);
+    ->catchBodies.insertAt(index, static_cast<Expression*>(catchExpr));
 }
 BinaryenExpressionRef BinaryenTryRemoveCatchBodyAt(BinaryenExpressionRef expr,
                                                    BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   return static_cast<Try*>(expression)->catchBodies.removeAt(index);
 }
 bool BinaryenTryHasCatchAll(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   return static_cast<Try*>(expression)->hasCatchAll();
 }
 const char* BinaryenTryGetDelegateTarget(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   return static_cast<Try*>(expression)->delegateTarget.str.data();
 }
 void BinaryenTrySetDelegateTarget(BinaryenExpressionRef expr,
                                   const char* delegateTarget) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   static_cast<Try*>(expression)->delegateTarget = delegateTarget;
 }
 bool BinaryenTryIsDelegate(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Try>());
   return static_cast<Try*>(expression)->isDelegate();
 }
 // Throw
 const char* BinaryenThrowGetTag(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Throw>());
   return static_cast<Throw*>(expression)->tag.str.data();
 }
 void BinaryenThrowSetTag(BinaryenExpressionRef expr, const char* tagName) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Throw>());
   static_cast<Throw*>(expression)->tag = tagName;
 }
 BinaryenIndex BinaryenThrowGetNumOperands(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Throw>());
   return static_cast<Throw*>(expression)->operands.size();
 }
 BinaryenExpressionRef BinaryenThrowGetOperandAt(BinaryenExpressionRef expr,
                                                 BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Throw>());
   assert(index < static_cast<Throw*>(expression)->operands.size());
   return static_cast<Throw*>(expression)->operands[index];
@@ -3916,166 +3916,166 @@
 void BinaryenThrowSetOperandAt(BinaryenExpressionRef expr,
                                BinaryenIndex index,
                                BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Throw>());
   assert(index < static_cast<Throw*>(expression)->operands.size());
   assert(operandExpr);
-  static_cast<Throw*>(expression)->operands[index] = (Expression*)operandExpr;
+  static_cast<Throw*>(expression)->operands[index] = static_cast<Expression*>(operandExpr);
 }
 BinaryenIndex BinaryenThrowAppendOperand(BinaryenExpressionRef expr,
                                          BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Throw>());
   assert(operandExpr);
   auto& list = static_cast<Throw*>(expression)->operands;
   auto index = list.size();
-  list.push_back((Expression*)operandExpr);
+  list.push_back(static_cast<Expression*>(operandExpr));
   return index;
 }
 void BinaryenThrowInsertOperandAt(BinaryenExpressionRef expr,
                                   BinaryenIndex index,
                                   BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Throw>());
   assert(operandExpr);
   static_cast<Throw*>(expression)
-    ->operands.insertAt(index, (Expression*)operandExpr);
+    ->operands.insertAt(index, static_cast<Expression*>(operandExpr));
 }
 BinaryenExpressionRef BinaryenThrowRemoveOperandAt(BinaryenExpressionRef expr,
                                                    BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Throw>());
   return static_cast<Throw*>(expression)->operands.removeAt(index);
 }
 // Rethrow
 const char* BinaryenRethrowGetTarget(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Rethrow>());
   return static_cast<Rethrow*>(expression)->target.str.data();
 }
 void BinaryenRethrowSetTarget(BinaryenExpressionRef expr, const char* target) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<Rethrow>());
   static_cast<Rethrow*>(expression)->target = target;
 }
 // TupleMake
 BinaryenIndex BinaryenTupleMakeGetNumOperands(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleMake>());
   return static_cast<TupleMake*>(expression)->operands.size();
 }
 BinaryenExpressionRef BinaryenTupleMakeGetOperandAt(BinaryenExpressionRef expr,
                                                     BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleMake>());
   return static_cast<TupleMake*>(expression)->operands[index];
 }
 void BinaryenTupleMakeSetOperandAt(BinaryenExpressionRef expr,
                                    BinaryenIndex index,
                                    BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleMake>());
   assert(index < static_cast<TupleMake*>(expression)->operands.size());
   assert(operandExpr);
   static_cast<TupleMake*>(expression)->operands[index] =
-    (Expression*)operandExpr;
+    static_cast<Expression*>(operandExpr);
 }
 BinaryenIndex
 BinaryenTupleMakeAppendOperand(BinaryenExpressionRef expr,
                                BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleMake>());
   assert(operandExpr);
   auto& list = static_cast<TupleMake*>(expression)->operands;
   auto index = list.size();
-  list.push_back((Expression*)operandExpr);
+  list.push_back(static_cast<Expression*>(operandExpr));
   return index;
 }
 void BinaryenTupleMakeInsertOperandAt(BinaryenExpressionRef expr,
                                       BinaryenIndex index,
                                       BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleMake>());
   assert(operandExpr);
   static_cast<TupleMake*>(expression)
-    ->operands.insertAt(index, (Expression*)operandExpr);
+    ->operands.insertAt(index, static_cast<Expression*>(operandExpr));
 }
 BinaryenExpressionRef
 BinaryenTupleMakeRemoveOperandAt(BinaryenExpressionRef expr,
                                  BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleMake>());
   return static_cast<TupleMake*>(expression)->operands.removeAt(index);
 }
 // TupleExtract
 BinaryenExpressionRef BinaryenTupleExtractGetTuple(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleExtract>());
   return static_cast<TupleExtract*>(expression)->tuple;
 }
 void BinaryenTupleExtractSetTuple(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef tupleExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleExtract>());
   assert(tupleExpr);
-  static_cast<TupleExtract*>(expression)->tuple = (Expression*)tupleExpr;
+  static_cast<TupleExtract*>(expression)->tuple = static_cast<Expression*>(tupleExpr);
 }
 BinaryenIndex BinaryenTupleExtractGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleExtract>());
   return static_cast<TupleExtract*>(expression)->index;
 }
 void BinaryenTupleExtractSetIndex(BinaryenExpressionRef expr,
                                   BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<TupleExtract>());
   static_cast<TupleExtract*>(expression)->index = index;
 }
 // RefI31
 BinaryenExpressionRef BinaryenRefI31GetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefI31>());
   return static_cast<RefI31*>(expression)->value;
 }
 void BinaryenRefI31SetValue(BinaryenExpressionRef expr,
                             BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefI31>());
   assert(valueExpr);
-  static_cast<RefI31*>(expression)->value = (Expression*)valueExpr;
+  static_cast<RefI31*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // I31Get
 BinaryenExpressionRef BinaryenI31GetGetI31(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<I31Get>());
   return static_cast<I31Get*>(expression)->i31;
 }
 void BinaryenI31GetSetI31(BinaryenExpressionRef expr,
                           BinaryenExpressionRef i31Expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<I31Get>());
   assert(i31Expr);
-  static_cast<I31Get*>(expression)->i31 = (Expression*)i31Expr;
+  static_cast<I31Get*>(expression)->i31 = static_cast<Expression*>(i31Expr);
 }
 bool BinaryenI31GetIsSigned(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<I31Get>());
   return static_cast<I31Get*>(expression)->signed_;
 }
 void BinaryenI31GetSetSigned(BinaryenExpressionRef expr, bool signed_) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<I31Get>());
   static_cast<I31Get*>(expression)->signed_ = signed_ != 0;
 }
 // CallRef
 BinaryenIndex BinaryenCallRefGetNumOperands(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   return static_cast<CallRef*>(expression)->operands.size();
 }
 BinaryenExpressionRef BinaryenCallRefGetOperandAt(BinaryenExpressionRef expr,
                                                   BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   assert(index < static_cast<CallRef*>(expression)->operands.size());
   return static_cast<CallRef*>(expression)->operands[index];
@@ -4083,150 +4083,150 @@
 void BinaryenCallRefSetOperandAt(BinaryenExpressionRef expr,
                                  BinaryenIndex index,
                                  BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   assert(index < static_cast<CallRef*>(expression)->operands.size());
   assert(operandExpr);
-  static_cast<CallRef*>(expression)->operands[index] = (Expression*)operandExpr;
+  static_cast<CallRef*>(expression)->operands[index] = static_cast<Expression*>(operandExpr);
 }
 BinaryenIndex BinaryenCallRefAppendOperand(BinaryenExpressionRef expr,
                                            BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   assert(operandExpr);
   auto& list = static_cast<CallRef*>(expression)->operands;
   auto index = list.size();
-  list.push_back((Expression*)operandExpr);
+  list.push_back(static_cast<Expression*>(operandExpr));
   return index;
 }
 void BinaryenCallRefInsertOperandAt(BinaryenExpressionRef expr,
                                     BinaryenIndex index,
                                     BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   assert(operandExpr);
   static_cast<CallRef*>(expression)
-    ->operands.insertAt(index, (Expression*)operandExpr);
+    ->operands.insertAt(index, static_cast<Expression*>(operandExpr));
 }
 BinaryenExpressionRef BinaryenCallRefRemoveOperandAt(BinaryenExpressionRef expr,
                                                      BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   return static_cast<CallRef*>(expression)->operands.removeAt(index);
 }
 BinaryenExpressionRef BinaryenCallRefGetTarget(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   return static_cast<CallRef*>(expression)->target;
 }
 void BinaryenCallRefSetTarget(BinaryenExpressionRef expr,
                               BinaryenExpressionRef targetExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   assert(targetExpr);
-  static_cast<CallRef*>(expression)->target = (Expression*)targetExpr;
+  static_cast<CallRef*>(expression)->target = static_cast<Expression*>(targetExpr);
 }
 bool BinaryenCallRefIsReturn(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   return static_cast<CallRef*>(expression)->isReturn;
 }
 void BinaryenCallRefSetReturn(BinaryenExpressionRef expr, bool isReturn) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<CallRef>());
   static_cast<CallRef*>(expression)->isReturn = isReturn;
 }
 // RefTest
 BinaryenExpressionRef BinaryenRefTestGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefTest>());
   return static_cast<RefTest*>(expression)->ref;
 }
 void BinaryenRefTestSetRef(BinaryenExpressionRef expr,
                            BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefTest>());
   assert(refExpr);
-  static_cast<RefTest*>(expression)->ref = (Expression*)refExpr;
+  static_cast<RefTest*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 BinaryenType BinaryenRefTestGetCastType(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefTest>());
   return static_cast<RefTest*>(expression)->castType.getID();
 }
 void BinaryenRefTestSetCastType(BinaryenExpressionRef expr,
                                 BinaryenType castType) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefTest>());
   static_cast<RefTest*>(expression)->castType = Type(castType);
 }
 // RefCast
 BinaryenExpressionRef BinaryenRefCastGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefCast>());
   return static_cast<RefCast*>(expression)->ref;
 }
 void BinaryenRefCastSetRef(BinaryenExpressionRef expr,
                            BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<RefCast>());
   assert(refExpr);
-  static_cast<RefCast*>(expression)->ref = (Expression*)refExpr;
+  static_cast<RefCast*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 // BrOn
 BinaryenOp BinaryenBrOnGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<BrOn>());
   return static_cast<BrOn*>(expression)->op;
 }
 void BinaryenBrOnSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<BrOn>());
   static_cast<BrOn*>(expression)->op = BrOnOp(op);
 }
 const char* BinaryenBrOnGetName(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<BrOn>());
   return static_cast<BrOn*>(expression)->name.str.data();
 }
 void BinaryenBrOnSetName(BinaryenExpressionRef expr, const char* nameStr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<BrOn>());
   assert(nameStr);
   static_cast<BrOn*>(expression)->name = nameStr;
 }
 BinaryenExpressionRef BinaryenBrOnGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<BrOn>());
   return static_cast<BrOn*>(expression)->ref;
 }
 void BinaryenBrOnSetRef(BinaryenExpressionRef expr,
                         BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<BrOn>());
   assert(refExpr);
-  static_cast<BrOn*>(expression)->ref = (Expression*)refExpr;
+  static_cast<BrOn*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 BinaryenType BinaryenBrOnGetCastType(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<BrOn>());
   return static_cast<BrOn*>(expression)->castType.getID();
 }
 void BinaryenBrOnSetCastType(BinaryenExpressionRef expr,
                              BinaryenType castType) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<BrOn>());
   static_cast<BrOn*>(expression)->castType = Type(castType);
 }
 // StructNew
 BinaryenIndex BinaryenStructNewGetNumOperands(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructNew>());
   return static_cast<StructNew*>(expression)->operands.size();
 }
 BinaryenExpressionRef BinaryenStructNewGetOperandAt(BinaryenExpressionRef expr,
                                                     BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructNew>());
   assert(index < static_cast<StructNew*>(expression)->operands.size());
   return static_cast<StructNew*>(expression)->operands[index];
@@ -4234,145 +4234,145 @@
 void BinaryenStructNewSetOperandAt(BinaryenExpressionRef expr,
                                    BinaryenIndex index,
                                    BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructNew>());
   assert(index < static_cast<StructNew*>(expression)->operands.size());
   assert(operandExpr);
   static_cast<StructNew*>(expression)->operands[index] =
-    (Expression*)operandExpr;
+    static_cast<Expression*>(operandExpr);
 }
 BinaryenIndex
 BinaryenStructNewAppendOperand(BinaryenExpressionRef expr,
                                BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructNew>());
   assert(operandExpr);
   auto& list = static_cast<StructNew*>(expression)->operands;
   auto index = list.size();
-  list.push_back((Expression*)operandExpr);
+  list.push_back(static_cast<Expression*>(operandExpr));
   return index;
 }
 void BinaryenStructNewInsertOperandAt(BinaryenExpressionRef expr,
                                       BinaryenIndex index,
                                       BinaryenExpressionRef operandExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructNew>());
   assert(operandExpr);
   static_cast<StructNew*>(expression)
-    ->operands.insertAt(index, (Expression*)operandExpr);
+    ->operands.insertAt(index, static_cast<Expression*>(operandExpr));
 }
 BinaryenExpressionRef
 BinaryenStructNewRemoveOperandAt(BinaryenExpressionRef expr,
                                  BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructNew>());
   return static_cast<StructNew*>(expression)->operands.removeAt(index);
 }
 // StructGet
 BinaryenIndex BinaryenStructGetGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructGet>());
   return static_cast<StructGet*>(expression)->index;
 }
 void BinaryenStructGetSetIndex(BinaryenExpressionRef expr,
                                BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructGet>());
   static_cast<StructGet*>(expression)->index = index;
 }
 BinaryenExpressionRef BinaryenStructGetGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructGet>());
   return static_cast<StructGet*>(expression)->ref;
 }
 void BinaryenStructGetSetRef(BinaryenExpressionRef expr,
                              BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructGet>());
   assert(refExpr);
-  static_cast<StructGet*>(expression)->ref = (Expression*)refExpr;
+  static_cast<StructGet*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 bool BinaryenStructGetIsSigned(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructGet>());
   return static_cast<StructGet*>(expression)->signed_;
 }
 void BinaryenStructGetSetSigned(BinaryenExpressionRef expr, bool signed_) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructGet>());
   static_cast<StructGet*>(expression)->signed_ = signed_;
 }
 // StructSet
 BinaryenIndex BinaryenStructSetGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructSet>());
   return static_cast<StructSet*>(expression)->index;
 }
 void BinaryenStructSetSetIndex(BinaryenExpressionRef expr,
                                BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructSet>());
   static_cast<StructSet*>(expression)->index = index;
 }
 BinaryenExpressionRef BinaryenStructSetGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructSet>());
   return static_cast<StructSet*>(expression)->ref;
 }
 void BinaryenStructSetSetRef(BinaryenExpressionRef expr,
                              BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructSet>());
   assert(refExpr);
-  static_cast<StructSet*>(expression)->ref = (Expression*)refExpr;
+  static_cast<StructSet*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 BinaryenExpressionRef BinaryenStructSetGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructSet>());
   return static_cast<StructSet*>(expression)->value;
 }
 void BinaryenStructSetSetValue(BinaryenExpressionRef expr,
                                BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StructSet>());
   assert(valueExpr);
-  static_cast<StructSet*>(expression)->value = (Expression*)valueExpr;
+  static_cast<StructSet*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // ArrayNew
 BinaryenExpressionRef BinaryenArrayNewGetInit(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNew>());
   return static_cast<ArrayNew*>(expression)->init;
 }
 void BinaryenArrayNewSetInit(BinaryenExpressionRef expr,
                              BinaryenExpressionRef initExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNew>());
   // may be null
-  static_cast<ArrayNew*>(expression)->init = (Expression*)initExpr;
+  static_cast<ArrayNew*>(expression)->init = static_cast<Expression*>(initExpr);
 }
 BinaryenExpressionRef BinaryenArrayNewGetSize(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNew>());
   return static_cast<ArrayNew*>(expression)->size;
 }
 void BinaryenArrayNewSetSize(BinaryenExpressionRef expr,
                              BinaryenExpressionRef sizeExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNew>());
   assert(sizeExpr);
-  static_cast<ArrayNew*>(expression)->size = (Expression*)sizeExpr;
+  static_cast<ArrayNew*>(expression)->size = static_cast<Expression*>(sizeExpr);
 }
 // ArrayNewFixed
 BinaryenIndex BinaryenArrayNewFixedGetNumValues(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewFixed>());
   return static_cast<ArrayNewFixed*>(expression)->values.size();
 }
 BinaryenExpressionRef
 BinaryenArrayNewFixedGetValueAt(BinaryenExpressionRef expr,
                                 BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewFixed>());
   assert(index < static_cast<ArrayNewFixed*>(expression)->values.size());
   return static_cast<ArrayNewFixed*>(expression)->values[index];
@@ -4380,674 +4380,674 @@
 void BinaryenArrayNewFixedSetValueAt(BinaryenExpressionRef expr,
                                      BinaryenIndex index,
                                      BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewFixed>());
   assert(index < static_cast<ArrayNewFixed*>(expression)->values.size());
   assert(valueExpr);
   static_cast<ArrayNewFixed*>(expression)->values[index] =
-    (Expression*)valueExpr;
+    static_cast<Expression*>(valueExpr);
 }
 BinaryenIndex
 BinaryenArrayNewFixedAppendValue(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewFixed>());
   assert(valueExpr);
   auto& list = static_cast<ArrayNewFixed*>(expression)->values;
   auto index = list.size();
-  list.push_back((Expression*)valueExpr);
+  list.push_back(static_cast<Expression*>(valueExpr));
   return index;
 }
 void BinaryenArrayNewFixedInsertValueAt(BinaryenExpressionRef expr,
                                         BinaryenIndex index,
                                         BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewFixed>());
   assert(valueExpr);
   static_cast<ArrayNewFixed*>(expression)
-    ->values.insertAt(index, (Expression*)valueExpr);
+    ->values.insertAt(index, static_cast<Expression*>(valueExpr));
 }
 BinaryenExpressionRef
 BinaryenArrayNewFixedRemoveValueAt(BinaryenExpressionRef expr,
                                    BinaryenIndex index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewFixed>());
   return static_cast<ArrayNewFixed*>(expression)->values.removeAt(index);
 }
 // ArrayNewData
 const char* BinaryenArrayNewDataGetSegment(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewData>());
   return static_cast<ArrayNewData*>(expression)->segment.str.data();
 }
 void BinaryenArrayNewDataSetSegment(BinaryenExpressionRef expr,
                                     const char* segment) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewData>());
   static_cast<ArrayNewData*>(expression)->segment = Name(segment);
 }
 BinaryenExpressionRef
 BinaryenArrayNewDataGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewData>());
   return static_cast<ArrayNewData*>(expression)->offset;
 }
 void BinaryenArrayNewDataSetOffset(BinaryenExpressionRef expr,
                                    BinaryenExpressionRef offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewData>());
   static_cast<ArrayNewData*>(expression)->offset = offset;
 }
 BinaryenExpressionRef BinaryenArrayNewDataGetSize(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewData>());
   return static_cast<ArrayNewData*>(expression)->size;
 }
 void BinaryenArrayNewDataSetSize(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef size) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewData>());
   static_cast<ArrayNewData*>(expression)->size = size;
 }
 // ArrayNewElem
 const char* BinaryenArrayNewElemGetSegment(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewElem>());
   return static_cast<ArrayNewElem*>(expression)->segment.str.data();
 }
 void BinaryenArrayNewElemSetSegment(BinaryenExpressionRef expr,
                                     const char* segment) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewElem>());
   static_cast<ArrayNewElem*>(expression)->segment = Name(segment);
 }
 BinaryenExpressionRef
 BinaryenArrayNewElemGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewElem>());
   return static_cast<ArrayNewElem*>(expression)->offset;
 }
 void BinaryenArrayNewElemSetOffset(BinaryenExpressionRef expr,
                                    BinaryenExpressionRef offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewElem>());
   static_cast<ArrayNewElem*>(expression)->offset = offset;
 }
 BinaryenExpressionRef BinaryenArrayNewElemGetSize(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewElem>());
   return static_cast<ArrayNewElem*>(expression)->size;
 }
 void BinaryenArrayNewElemSetSize(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef size) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayNewElem>());
   static_cast<ArrayNewElem*>(expression)->size = size;
 }
 // ArrayGet
 BinaryenExpressionRef BinaryenArrayGetGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayGet>());
   return static_cast<ArrayGet*>(expression)->ref;
 }
 void BinaryenArrayGetSetRef(BinaryenExpressionRef expr,
                             BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayGet>());
   assert(refExpr);
-  static_cast<ArrayGet*>(expression)->ref = (Expression*)refExpr;
+  static_cast<ArrayGet*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 BinaryenExpressionRef BinaryenArrayGetGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayGet>());
   return static_cast<ArrayGet*>(expression)->index;
 }
 void BinaryenArrayGetSetIndex(BinaryenExpressionRef expr,
                               BinaryenExpressionRef indexExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayGet>());
   assert(indexExpr);
-  static_cast<ArrayGet*>(expression)->index = (Expression*)indexExpr;
+  static_cast<ArrayGet*>(expression)->index = static_cast<Expression*>(indexExpr);
 }
 bool BinaryenArrayGetIsSigned(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayGet>());
   return static_cast<ArrayGet*>(expression)->signed_;
 }
 void BinaryenArrayGetSetSigned(BinaryenExpressionRef expr, bool signed_) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayGet>());
   static_cast<ArrayGet*>(expression)->signed_ = signed_;
 }
 // ArraySet
 BinaryenExpressionRef BinaryenArraySetGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArraySet>());
   return static_cast<ArraySet*>(expression)->ref;
 }
 void BinaryenArraySetSetRef(BinaryenExpressionRef expr,
                             BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArraySet>());
   assert(refExpr);
-  static_cast<ArraySet*>(expression)->ref = (Expression*)refExpr;
+  static_cast<ArraySet*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 BinaryenExpressionRef BinaryenArraySetGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArraySet>());
   return static_cast<ArraySet*>(expression)->index;
 }
 void BinaryenArraySetSetIndex(BinaryenExpressionRef expr,
                               BinaryenExpressionRef indexExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArraySet>());
   assert(indexExpr);
-  static_cast<ArraySet*>(expression)->index = (Expression*)indexExpr;
+  static_cast<ArraySet*>(expression)->index = static_cast<Expression*>(indexExpr);
 }
 BinaryenExpressionRef BinaryenArraySetGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArraySet>());
   return static_cast<ArraySet*>(expression)->value;
 }
 void BinaryenArraySetSetValue(BinaryenExpressionRef expr,
                               BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArraySet>());
   assert(valueExpr);
-  static_cast<ArraySet*>(expression)->value = (Expression*)valueExpr;
+  static_cast<ArraySet*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 // ArrayLen
 BinaryenExpressionRef BinaryenArrayLenGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayLen>());
   return static_cast<ArrayLen*>(expression)->ref;
 }
 void BinaryenArrayLenSetRef(BinaryenExpressionRef expr,
                             BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayLen>());
   assert(refExpr);
-  static_cast<ArrayLen*>(expression)->ref = (Expression*)refExpr;
+  static_cast<ArrayLen*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 // ArrayFill
 BinaryenExpressionRef BinaryenArrayFillGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayFill>());
   return static_cast<ArrayFill*>(expression)->ref;
 }
 void BinaryenArrayFillSetRef(BinaryenExpressionRef expr,
                              BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayFill>());
   assert(refExpr);
-  static_cast<ArrayFill*>(expression)->ref = (Expression*)refExpr;
+  static_cast<ArrayFill*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 BinaryenExpressionRef BinaryenArrayFillGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayFill>());
   return static_cast<ArrayFill*>(expression)->index;
 }
 void BinaryenArrayFillSetIndex(BinaryenExpressionRef expr,
                                BinaryenExpressionRef indexExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayFill>());
   assert(indexExpr);
-  static_cast<ArrayFill*>(expression)->index = (Expression*)indexExpr;
+  static_cast<ArrayFill*>(expression)->index = static_cast<Expression*>(indexExpr);
 }
 BinaryenExpressionRef BinaryenArrayFillGetValue(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayFill>());
   return static_cast<ArrayFill*>(expression)->value;
 }
 void BinaryenArrayFillSetValue(BinaryenExpressionRef expr,
                                BinaryenExpressionRef valueExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayFill>());
   assert(valueExpr);
-  static_cast<ArrayFill*>(expression)->value = (Expression*)valueExpr;
+  static_cast<ArrayFill*>(expression)->value = static_cast<Expression*>(valueExpr);
 }
 BinaryenExpressionRef BinaryenArrayFillGetSize(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayFill>());
   return static_cast<ArrayFill*>(expression)->size;
 }
 void BinaryenArrayFillSetSize(BinaryenExpressionRef expr,
                               BinaryenExpressionRef sizeExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayFill>());
   assert(sizeExpr);
-  static_cast<ArrayFill*>(expression)->size = (Expression*)sizeExpr;
+  static_cast<ArrayFill*>(expression)->size = static_cast<Expression*>(sizeExpr);
 }
 // ArrayCopy
 BinaryenExpressionRef BinaryenArrayCopyGetDestRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   return static_cast<ArrayCopy*>(expression)->destRef;
 }
 void BinaryenArrayCopySetDestRef(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef destRefExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   assert(destRefExpr);
-  static_cast<ArrayCopy*>(expression)->destRef = (Expression*)destRefExpr;
+  static_cast<ArrayCopy*>(expression)->destRef = static_cast<Expression*>(destRefExpr);
 }
 BinaryenExpressionRef
 BinaryenArrayCopyGetDestIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   return static_cast<ArrayCopy*>(expression)->destIndex;
 }
 void BinaryenArrayCopySetDestIndex(BinaryenExpressionRef expr,
                                    BinaryenExpressionRef destIndexExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   assert(destIndexExpr);
-  static_cast<ArrayCopy*>(expression)->destIndex = (Expression*)destIndexExpr;
+  static_cast<ArrayCopy*>(expression)->destIndex = static_cast<Expression*>(destIndexExpr);
 }
 BinaryenExpressionRef BinaryenArrayCopyGetSrcRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   return static_cast<ArrayCopy*>(expression)->srcRef;
 }
 void BinaryenArrayCopySetSrcRef(BinaryenExpressionRef expr,
                                 BinaryenExpressionRef srcRefExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   assert(srcRefExpr);
-  static_cast<ArrayCopy*>(expression)->srcRef = (Expression*)srcRefExpr;
+  static_cast<ArrayCopy*>(expression)->srcRef = static_cast<Expression*>(srcRefExpr);
 }
 BinaryenExpressionRef BinaryenArrayCopyGetSrcIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   return static_cast<ArrayCopy*>(expression)->srcIndex;
 }
 void BinaryenArrayCopySetSrcIndex(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef srcIndexExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   assert(srcIndexExpr);
-  static_cast<ArrayCopy*>(expression)->srcIndex = (Expression*)srcIndexExpr;
+  static_cast<ArrayCopy*>(expression)->srcIndex = static_cast<Expression*>(srcIndexExpr);
 }
 BinaryenExpressionRef BinaryenArrayCopyGetLength(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   return static_cast<ArrayCopy*>(expression)->length;
 }
 void BinaryenArrayCopySetLength(BinaryenExpressionRef expr,
                                 BinaryenExpressionRef lengthExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayCopy>());
   assert(lengthExpr);
-  static_cast<ArrayCopy*>(expression)->length = (Expression*)lengthExpr;
+  static_cast<ArrayCopy*>(expression)->length = static_cast<Expression*>(lengthExpr);
 }
 // ArrayInitData
 const char* BinaryenArrayInitDataGetSegment(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   return static_cast<ArrayInitData*>(expression)->segment.str.data();
 }
 void BinaryenArrayInitDataSetSegment(BinaryenExpressionRef expr,
                                      const char* segment) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   static_cast<ArrayInitData*>(expression)->segment = Name(segment);
 }
 BinaryenExpressionRef BinaryenArrayInitDataGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   return static_cast<ArrayInitData*>(expression)->ref;
 }
 void BinaryenArrayInitDataSetRef(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef ref) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   static_cast<ArrayInitData*>(expression)->ref = ref;
 }
 BinaryenExpressionRef
 BinaryenArrayInitDataGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   return static_cast<ArrayInitData*>(expression)->index;
 }
 void BinaryenArrayInitDataSetIndex(BinaryenExpressionRef expr,
                                    BinaryenExpressionRef index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   static_cast<ArrayInitData*>(expression)->index = index;
 }
 BinaryenExpressionRef
 BinaryenArrayInitDataGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   return static_cast<ArrayInitData*>(expression)->offset;
 }
 void BinaryenArrayInitDataSetOffset(BinaryenExpressionRef expr,
                                     BinaryenExpressionRef offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   static_cast<ArrayInitData*>(expression)->offset = offset;
 }
 BinaryenExpressionRef BinaryenArrayInitDataGetSize(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   return static_cast<ArrayInitData*>(expression)->size;
 }
 void BinaryenArrayInitDataSetSize(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef size) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitData>());
   static_cast<ArrayInitData*>(expression)->size = size;
 }
 // ArrayInitElem
 const char* BinaryenArrayInitElemGetSegment(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   return static_cast<ArrayInitElem*>(expression)->segment.str.data();
 }
 void BinaryenArrayInitElemSetSegment(BinaryenExpressionRef expr,
                                      const char* segment) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   static_cast<ArrayInitElem*>(expression)->segment = Name(segment);
 }
 BinaryenExpressionRef BinaryenArrayInitElemGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   return static_cast<ArrayInitElem*>(expression)->ref;
 }
 void BinaryenArrayInitElemSetRef(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef ref) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   static_cast<ArrayInitElem*>(expression)->ref = ref;
 }
 BinaryenExpressionRef
 BinaryenArrayInitElemGetIndex(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   return static_cast<ArrayInitElem*>(expression)->index;
 }
 void BinaryenArrayInitElemSetIndex(BinaryenExpressionRef expr,
                                    BinaryenExpressionRef index) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   static_cast<ArrayInitElem*>(expression)->index = index;
 }
 BinaryenExpressionRef
 BinaryenArrayInitElemGetOffset(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   return static_cast<ArrayInitElem*>(expression)->offset;
 }
 void BinaryenArrayInitElemSetOffset(BinaryenExpressionRef expr,
                                     BinaryenExpressionRef offset) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   static_cast<ArrayInitElem*>(expression)->offset = offset;
 }
 BinaryenExpressionRef BinaryenArrayInitElemGetSize(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   return static_cast<ArrayInitElem*>(expression)->size;
 }
 void BinaryenArrayInitElemSetSize(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef size) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<ArrayInitElem>());
   static_cast<ArrayInitElem*>(expression)->size = size;
 }
 // StringNew
 BinaryenOp BinaryenStringNewGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringNew>());
   return static_cast<StringNew*>(expression)->op;
 }
 void BinaryenStringNewSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringNew>());
   static_cast<StringNew*>(expression)->op = StringNewOp(op);
 }
 BinaryenExpressionRef BinaryenStringNewGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringNew>());
   return static_cast<StringNew*>(expression)->ref;
 }
 void BinaryenStringNewSetRef(BinaryenExpressionRef expr,
                              BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringNew>());
   assert(refExpr);
-  static_cast<StringNew*>(expression)->ref = (Expression*)refExpr;
+  static_cast<StringNew*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 BinaryenExpressionRef BinaryenStringNewGetStart(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringNew>());
   return static_cast<StringNew*>(expression)->start;
 }
 void BinaryenStringNewSetStart(BinaryenExpressionRef expr,
                                BinaryenExpressionRef startExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringNew>());
   // may be null (GC only)
-  static_cast<StringNew*>(expression)->start = (Expression*)startExpr;
+  static_cast<StringNew*>(expression)->start = static_cast<Expression*>(startExpr);
 }
 BinaryenExpressionRef BinaryenStringNewGetEnd(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringNew>());
   return static_cast<StringNew*>(expression)->end;
 }
 void BinaryenStringNewSetEnd(BinaryenExpressionRef expr,
                              BinaryenExpressionRef endExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringNew>());
   // may be null (GC only)
-  static_cast<StringNew*>(expression)->end = (Expression*)endExpr;
+  static_cast<StringNew*>(expression)->end = static_cast<Expression*>(endExpr);
 }
 // StringConst
 const char* BinaryenStringConstGetString(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringConst>());
   return static_cast<StringConst*>(expression)->string.str.data();
 }
 void BinaryenStringConstSetString(BinaryenExpressionRef expr,
                                   const char* stringStr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringConst>());
   assert(stringStr);
   static_cast<StringConst*>(expression)->string = stringStr;
 }
 // StringMeasure
 BinaryenOp BinaryenStringMeasureGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringMeasure>());
   return static_cast<StringMeasure*>(expression)->op;
 }
 void BinaryenStringMeasureSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringMeasure>());
   static_cast<StringMeasure*>(expression)->op = StringMeasureOp(op);
 }
 BinaryenExpressionRef BinaryenStringMeasureGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringMeasure>());
   return static_cast<StringMeasure*>(expression)->ref;
 }
 void BinaryenStringMeasureSetRef(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringMeasure>());
   assert(refExpr);
-  static_cast<StringMeasure*>(expression)->ref = (Expression*)refExpr;
+  static_cast<StringMeasure*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 // StringEncode
 BinaryenOp BinaryenStringEncodeGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEncode>());
   return static_cast<StringEncode*>(expression)->op;
 }
 void BinaryenStringEncodeSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEncode>());
   static_cast<StringEncode*>(expression)->op = StringEncodeOp(op);
 }
 BinaryenExpressionRef BinaryenStringEncodeGetStr(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEncode>());
   return static_cast<StringEncode*>(expression)->str;
 }
 void BinaryenStringEncodeSetStr(BinaryenExpressionRef expr,
                                 BinaryenExpressionRef strExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEncode>());
   assert(strExpr);
-  static_cast<StringEncode*>(expression)->str = (Expression*)strExpr;
+  static_cast<StringEncode*>(expression)->str = static_cast<Expression*>(strExpr);
 }
 BinaryenExpressionRef BinaryenStringEncodeGetArray(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEncode>());
   return static_cast<StringEncode*>(expression)->array;
 }
 void BinaryenStringEncodeSetArray(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef arrayExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEncode>());
   assert(arrayExpr);
-  static_cast<StringEncode*>(expression)->array = (Expression*)arrayExpr;
+  static_cast<StringEncode*>(expression)->array = static_cast<Expression*>(arrayExpr);
 }
 BinaryenExpressionRef BinaryenStringEncodeGetStart(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEncode>());
   return static_cast<StringEncode*>(expression)->start;
 }
 void BinaryenStringEncodeSetStart(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef startExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEncode>());
   // may be null (GC only)
-  static_cast<StringEncode*>(expression)->start = (Expression*)startExpr;
+  static_cast<StringEncode*>(expression)->start = static_cast<Expression*>(startExpr);
 }
 // StringConcat
 BinaryenExpressionRef BinaryenStringConcatGetLeft(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringConcat>());
   return static_cast<StringConcat*>(expression)->left;
 }
 void BinaryenStringConcatSetLeft(BinaryenExpressionRef expr,
                                  BinaryenExpressionRef leftExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringConcat>());
   assert(leftExpr);
-  static_cast<StringConcat*>(expression)->left = (Expression*)leftExpr;
+  static_cast<StringConcat*>(expression)->left = static_cast<Expression*>(leftExpr);
 }
 BinaryenExpressionRef BinaryenStringConcatGetRight(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringConcat>());
   return static_cast<StringConcat*>(expression)->right;
 }
 void BinaryenStringConcatSetRight(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef rightExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringConcat>());
   assert(rightExpr);
-  static_cast<StringConcat*>(expression)->right = (Expression*)rightExpr;
+  static_cast<StringConcat*>(expression)->right = static_cast<Expression*>(rightExpr);
 }
 // StringEq
 BinaryenOp BinaryenStringEqGetOp(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEq>());
   return static_cast<StringEq*>(expression)->op;
 }
 void BinaryenStringEqSetOp(BinaryenExpressionRef expr, BinaryenOp op) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEq>());
   static_cast<StringEq*>(expression)->op = StringEqOp(op);
 }
 BinaryenExpressionRef BinaryenStringEqGetLeft(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEq>());
   return static_cast<StringEq*>(expression)->left;
 }
 void BinaryenStringEqSetLeft(BinaryenExpressionRef expr,
                              BinaryenExpressionRef leftExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEq>());
   assert(leftExpr);
-  static_cast<StringEq*>(expression)->left = (Expression*)leftExpr;
+  static_cast<StringEq*>(expression)->left = static_cast<Expression*>(leftExpr);
 }
 BinaryenExpressionRef BinaryenStringEqGetRight(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEq>());
   return static_cast<StringEq*>(expression)->right;
 }
 void BinaryenStringEqSetRight(BinaryenExpressionRef expr,
                               BinaryenExpressionRef rightExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringEq>());
   assert(rightExpr);
-  static_cast<StringEq*>(expression)->right = (Expression*)rightExpr;
+  static_cast<StringEq*>(expression)->right = static_cast<Expression*>(rightExpr);
 }
 // StringWTF16Get
 BinaryenExpressionRef BinaryenStringWTF16GetGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringWTF16Get>());
   return static_cast<StringWTF16Get*>(expression)->ref;
 }
 void BinaryenStringWTF16GetSetRef(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringWTF16Get>());
   assert(refExpr);
-  static_cast<StringWTF16Get*>(expression)->ref = (Expression*)refExpr;
+  static_cast<StringWTF16Get*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 BinaryenExpressionRef BinaryenStringWTF16GetGetPos(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringWTF16Get>());
   return static_cast<StringWTF16Get*>(expression)->pos;
 }
 void BinaryenStringWTF16GetSetPos(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef posExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringWTF16Get>());
   assert(posExpr);
-  static_cast<StringWTF16Get*>(expression)->pos = (Expression*)posExpr;
+  static_cast<StringWTF16Get*>(expression)->pos = static_cast<Expression*>(posExpr);
 }
 // StringSliceWTF
 BinaryenExpressionRef BinaryenStringSliceWTFGetRef(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringSliceWTF>());
   return static_cast<StringSliceWTF*>(expression)->ref;
 }
 void BinaryenStringSliceWTFSetRef(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef refExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringSliceWTF>());
   assert(refExpr);
-  static_cast<StringSliceWTF*>(expression)->ref = (Expression*)refExpr;
+  static_cast<StringSliceWTF*>(expression)->ref = static_cast<Expression*>(refExpr);
 }
 BinaryenExpressionRef
 BinaryenStringSliceWTFGetStart(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringSliceWTF>());
   return static_cast<StringSliceWTF*>(expression)->start;
 }
 void BinaryenStringSliceWTFSetStart(BinaryenExpressionRef expr,
                                     BinaryenExpressionRef startExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringSliceWTF>());
   assert(startExpr);
-  static_cast<StringSliceWTF*>(expression)->start = (Expression*)startExpr;
+  static_cast<StringSliceWTF*>(expression)->start = static_cast<Expression*>(startExpr);
 }
 BinaryenExpressionRef BinaryenStringSliceWTFGetEnd(BinaryenExpressionRef expr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringSliceWTF>());
   return static_cast<StringSliceWTF*>(expression)->end;
 }
 void BinaryenStringSliceWTFSetEnd(BinaryenExpressionRef expr,
                                   BinaryenExpressionRef endExpr) {
-  auto* expression = (Expression*)expr;
+  auto* expression = static_cast<Expression*>(expr);
   assert(expression->is<StringSliceWTF>());
   assert(endExpr);
-  static_cast<StringSliceWTF*>(expression)->end = (Expression*)endExpr;
+  static_cast<StringSliceWTF*>(expression)->end = static_cast<Expression*>(endExpr);
 }
 
 // Functions
@@ -5064,13 +5064,13 @@
   for (BinaryenIndex i = 0; i < numVarTypes; i++) {
     ret->vars.push_back(Type(varTypes[i]));
   }
-  ret->body = (Expression*)body;
+  ret->body = static_cast<Expression*>(body);
 
   // Lock. This can be called from multiple threads at once, and is a
   // point where they all access and modify the module.
   {
     std::lock_guard<std::mutex> lock(BinaryenFunctionMutex);
-    ((Module*)module)->addFunction(ret);
+    (static_cast<Module*>(module))->addFunction(ret);
   }
 
   return ret;
@@ -5098,17 +5098,17 @@
 }
 BinaryenFunctionRef BinaryenGetFunction(BinaryenModuleRef module,
                                         const char* name) {
-  return ((Module*)module)->getFunctionOrNull(name);
+  return (static_cast<Module*>(module))->getFunctionOrNull(name);
 }
 void BinaryenRemoveFunction(BinaryenModuleRef module, const char* name) {
-  ((Module*)module)->removeFunction(name);
+  (static_cast<Module*>(module))->removeFunction(name);
 }
 BinaryenIndex BinaryenGetNumFunctions(BinaryenModuleRef module) {
-  return ((Module*)module)->functions.size();
+  return (static_cast<Module*>(module))->functions.size();
 }
 BinaryenFunctionRef BinaryenGetFunctionByIndex(BinaryenModuleRef module,
                                                BinaryenIndex index) {
-  const auto& functions = ((Module*)module)->functions;
+  const auto& functions = (static_cast<Module*>(module))->functions;
   if (functions.size() <= index) {
     Fatal() << "invalid function index.";
   }
@@ -5126,23 +5126,23 @@
   ret->setExplicitName(name);
   ret->type = Type(type);
   ret->mutable_ = mutable_;
-  ret->init = (Expression*)init;
-  ((Module*)module)->addGlobal(ret);
+  ret->init = static_cast<Expression*>(init);
+  (static_cast<Module*>(module))->addGlobal(ret);
   return ret;
 }
 BinaryenGlobalRef BinaryenGetGlobal(BinaryenModuleRef module,
                                     const char* name) {
-  return ((Module*)module)->getGlobalOrNull(name);
+  return (static_cast<Module*>(module))->getGlobalOrNull(name);
 }
 void BinaryenRemoveGlobal(BinaryenModuleRef module, const char* name) {
-  ((Module*)module)->removeGlobal(name);
+  (static_cast<Module*>(module))->removeGlobal(name);
 }
 BinaryenIndex BinaryenGetNumGlobals(BinaryenModuleRef module) {
-  return ((Module*)module)->globals.size();
+  return (static_cast<Module*>(module))->globals.size();
 }
 BinaryenGlobalRef BinaryenGetGlobalByIndex(BinaryenModuleRef module,
                                            BinaryenIndex index) {
-  const auto& globals = ((Module*)module)->globals;
+  const auto& globals = (static_cast<Module*>(module))->globals;
   if (globals.size() <= index) {
     Fatal() << "invalid global index.";
   }
@@ -5158,15 +5158,15 @@
   auto* ret = new Tag();
   ret->setExplicitName(name);
   ret->type = Signature(Type(params), Type(results));
-  ((Module*)module)->addTag(ret);
+  (static_cast<Module*>(module))->addTag(ret);
   return ret;
 }
 
 BinaryenTagRef BinaryenGetTag(BinaryenModuleRef module, const char* name) {
-  return ((Module*)module)->getTagOrNull(name);
+  return (static_cast<Module*>(module))->getTagOrNull(name);
 }
 void BinaryenRemoveTag(BinaryenModuleRef module, const char* name) {
-  ((Module*)module)->removeTag(name);
+  (static_cast<Module*>(module))->removeTag(name);
 }
 
 // Imports
@@ -5177,7 +5177,7 @@
                                const char* externalBaseName,
                                BinaryenType params,
                                BinaryenType results) {
-  auto* func = ((Module*)module)->getFunctionOrNull(internalName);
+  auto* func = (static_cast<Module*>(module))->getFunctionOrNull(internalName);
   if (func == nullptr) {
     auto func = std::make_unique<Function>();
     func->name = internalName;
@@ -5186,7 +5186,7 @@
     // TODO: Take a Type rather than params and results.
     func->type =
       Type(Signature(Type(params), Type(results)), NonNullable, Inexact);
-    ((Module*)module)->addFunction(std::move(func));
+    (static_cast<Module*>(module))->addFunction(std::move(func));
   } else {
     // already exists so just set module and base
     func->module = externalModuleName;
@@ -5197,13 +5197,13 @@
                             const char* internalName,
                             const char* externalModuleName,
                             const char* externalBaseName) {
-  auto* table = ((Module*)module)->getTableOrNull(internalName);
+  auto* table = (static_cast<Module*>(module))->getTableOrNull(internalName);
   if (table == nullptr) {
     auto table = std::make_unique<Table>();
     table->name = internalName;
     table->module = externalModuleName;
     table->base = externalBaseName;
-    ((Module*)module)->addTable(std::move(table));
+    (static_cast<Module*>(module))->addTable(std::move(table));
   } else {
     // already exists so just set module and base
     table->module = externalModuleName;
@@ -5215,14 +5215,14 @@
                              const char* externalModuleName,
                              const char* externalBaseName,
                              uint8_t shared) {
-  auto* memory = ((Module*)module)->getMemoryOrNull(internalName);
+  auto* memory = (static_cast<Module*>(module))->getMemoryOrNull(internalName);
   if (memory == nullptr) {
     auto memory = std::make_unique<Memory>();
     memory->name = internalName;
     memory->module = externalModuleName;
     memory->base = externalBaseName;
     memory->shared = shared;
-    ((Module*)module)->addMemory(std::move(memory));
+    (static_cast<Module*>(module))->addMemory(std::move(memory));
   } else {
     // already exists so just set module and base
     memory->module = externalModuleName;
@@ -5235,7 +5235,7 @@
                              const char* externalBaseName,
                              BinaryenType globalType,
                              bool mutable_) {
-  auto* glob = ((Module*)module)->getGlobalOrNull(internalName);
+  auto* glob = (static_cast<Module*>(module))->getGlobalOrNull(internalName);
   if (glob == nullptr) {
     auto glob = std::make_unique<Global>();
     glob->name = internalName;
@@ -5243,7 +5243,7 @@
     glob->base = externalBaseName;
     glob->type = Type(globalType);
     glob->mutable_ = mutable_;
-    ((Module*)module)->addGlobal(std::move(glob));
+    (static_cast<Module*>(module))->addGlobal(std::move(glob));
   } else {
     // already exists so just set module and base
     glob->module = externalModuleName;
@@ -5256,14 +5256,14 @@
                           const char* externalBaseName,
                           BinaryenType params,
                           BinaryenType results) {
-  auto* tag = ((Module*)module)->getTagOrNull(internalName);
+  auto* tag = (static_cast<Module*>(module))->getTagOrNull(internalName);
   if (tag == nullptr) {
     auto tag = std::make_unique<Tag>();
     tag->name = internalName;
     tag->module = externalModuleName;
     tag->base = externalBaseName;
     tag->type = Signature(Type(params), Type(results));
-    ((Module*)module)->addTag(std::move(tag));
+    (static_cast<Module*>(module))->addTag(std::move(tag));
   } else {
     // already exists so just set module and base
     tag->module = externalModuleName;
@@ -5282,50 +5282,50 @@
                                             const char* internalName,
                                             const char* externalName) {
   auto* ret = new Export(externalName, ExternalKind::Function, internalName);
-  ((Module*)module)->addExport(ret);
+  (static_cast<Module*>(module))->addExport(ret);
   return ret;
 }
 BinaryenExportRef BinaryenAddTableExport(BinaryenModuleRef module,
                                          const char* internalName,
                                          const char* externalName) {
   auto* ret = new Export(externalName, ExternalKind::Table, internalName);
-  ((Module*)module)->addExport(ret);
+  (static_cast<Module*>(module))->addExport(ret);
   return ret;
 }
 BinaryenExportRef BinaryenAddMemoryExport(BinaryenModuleRef module,
                                           const char* internalName,
                                           const char* externalName) {
   auto* ret = new Export(externalName, ExternalKind::Memory, internalName);
-  ((Module*)module)->addExport(ret);
+  (static_cast<Module*>(module))->addExport(ret);
   return ret;
 }
 BinaryenExportRef BinaryenAddGlobalExport(BinaryenModuleRef module,
                                           const char* internalName,
                                           const char* externalName) {
   auto* ret = new Export(externalName, ExternalKind::Global, internalName);
-  ((Module*)module)->addExport(ret);
+  (static_cast<Module*>(module))->addExport(ret);
   return ret;
 }
 BinaryenExportRef BinaryenAddTagExport(BinaryenModuleRef module,
                                        const char* internalName,
                                        const char* externalName) {
   auto* ret = new Export(externalName, ExternalKind::Tag, internalName);
-  ((Module*)module)->addExport(ret);
+  (static_cast<Module*>(module))->addExport(ret);
   return ret;
 }
 BinaryenExportRef BinaryenGetExport(BinaryenModuleRef module,
                                     const char* externalName) {
-  return ((Module*)module)->getExportOrNull(externalName);
+  return (static_cast<Module*>(module))->getExportOrNull(externalName);
 }
 void BinaryenRemoveExport(BinaryenModuleRef module, const char* externalName) {
-  ((Module*)module)->removeExport(externalName);
+  (static_cast<Module*>(module))->removeExport(externalName);
 }
 BinaryenIndex BinaryenGetNumExports(BinaryenModuleRef module) {
-  return ((Module*)module)->exports.size();
+  return (static_cast<Module*>(module))->exports.size();
 }
 BinaryenExportRef BinaryenGetExportByIndex(BinaryenModuleRef module,
                                            BinaryenIndex index) {
-  const auto& exports = ((Module*)module)->exports;
+  const auto& exports = (static_cast<Module*>(module))->exports;
   if (exports.size() <= index) {
     Fatal() << "invalid export index.";
   }
@@ -5339,20 +5339,20 @@
                                   BinaryenType tableType) {
   auto table = Builder::makeTable(name, Type(tableType), initial, maximum);
   table->hasExplicitName = true;
-  return ((Module*)module)->addTable(std::move(table));
+  return (static_cast<Module*>(module))->addTable(std::move(table));
 }
 void BinaryenRemoveTable(BinaryenModuleRef module, const char* table) {
-  ((Module*)module)->removeTable(table);
+  (static_cast<Module*>(module))->removeTable(table);
 }
 BinaryenIndex BinaryenGetNumTables(BinaryenModuleRef module) {
-  return ((Module*)module)->tables.size();
+  return (static_cast<Module*>(module))->tables.size();
 }
 BinaryenTableRef BinaryenGetTable(BinaryenModuleRef module, const char* name) {
-  return ((Module*)module)->getTableOrNull(name);
+  return (static_cast<Module*>(module))->getTableOrNull(name);
 }
 BinaryenTableRef BinaryenGetTableByIndex(BinaryenModuleRef module,
                                          BinaryenIndex index) {
-  const auto& tables = ((Module*)module)->tables;
+  const auto& tables = (static_cast<Module*>(module))->tables;
   if (tables.size() <= index) {
     Fatal() << "invalid table index.";
   }
@@ -5365,17 +5365,17 @@
                                 const char** funcNames,
                                 BinaryenIndex numFuncNames,
                                 BinaryenExpressionRef offset) {
-  auto segment = std::make_unique<ElementSegment>(table, (Expression*)offset);
+  auto segment = std::make_unique<ElementSegment>(table, static_cast<Expression*>(offset));
   segment->setExplicitName(name);
   for (BinaryenIndex i = 0; i < numFuncNames; i++) {
-    auto* func = ((Module*)module)->getFunctionOrNull(funcNames[i]);
+    auto* func = (static_cast<Module*>(module))->getFunctionOrNull(funcNames[i]);
     if (func == nullptr) {
       Fatal() << "invalid function '" << funcNames[i] << "'.";
     }
     segment->data.push_back(
-      Builder(*(Module*)module).makeRefFunc(funcNames[i]));
+      Builder(*static_cast<Module*>(module)).makeRefFunc(funcNames[i]));
   }
-  return ((Module*)module)->addElementSegment(std::move(segment));
+  return (static_cast<Module*>(module))->addElementSegment(std::move(segment));
 }
 BinaryenElementSegmentRef
 BinaryenAddPassiveElementSegment(BinaryenModuleRef module,
@@ -5385,49 +5385,50 @@
   auto segment = std::make_unique<ElementSegment>();
   segment->setExplicitName(name);
   for (BinaryenIndex i = 0; i < numFuncNames; i++) {
-    auto* func = ((Module*)module)->getFunctionOrNull(funcNames[i]);
+    auto* func = (static_cast<Module*>(module))->getFunctionOrNull(funcNames[i]);
     if (func == nullptr) {
       Fatal() << "invalid function '" << funcNames[i] << "'.";
     }
     segment->data.push_back(
-      Builder(*(Module*)module).makeRefFunc(funcNames[i]));
+      Builder(*static_cast<Module*>(module)).makeRefFunc(funcNames[i]));
   }
-  return ((Module*)module)->addElementSegment(std::move(segment));
+  return (static_cast<Module*>(module))->addElementSegment(std::move(segment));
 }
 void BinaryenRemoveElementSegment(BinaryenModuleRef module, const char* name) {
-  ((Module*)module)->removeElementSegment(name);
+  (static_cast<Module*>(module))->removeElementSegment(name);
 }
 BinaryenElementSegmentRef BinaryenGetElementSegment(BinaryenModuleRef module,
                                                     const char* name) {
-  return ((Module*)module)->getElementSegmentOrNull(name);
+  return (static_cast<Module*>(module))->getElementSegmentOrNull(name);
 }
 BinaryenElementSegmentRef
 BinaryenGetElementSegmentByIndex(BinaryenModuleRef module,
                                  BinaryenIndex index) {
-  const auto& elementSegments = ((Module*)module)->elementSegments;
+  const auto& elementSegments = (static_cast<Module*>(module))->elementSegments;
   if (elementSegments.size() <= index) {
     Fatal() << "invalid table index.";
   }
   return elementSegments[index].get();
 }
 BinaryenIndex BinaryenGetNumElementSegments(BinaryenModuleRef module) {
-  return ((Module*)module)->elementSegments.size();
+  return (static_cast<Module*>(module))->elementSegments.size();
 }
 BinaryenExpressionRef
 BinaryenElementSegmentGetOffset(BinaryenElementSegmentRef elem) {
-  if (((ElementSegment*)elem)->table.isNull()) {
+  if ((static_cast<ElementSegment*>(elem))->table.isNull()) {
     Fatal() << "elem segment is passive.";
   }
-  return ((ElementSegment*)elem)->offset;
+  return (static_cast<ElementSegment*>(elem))->offset;
 }
 BinaryenIndex BinaryenElementSegmentGetLength(BinaryenElementSegmentRef elem) {
-  return ((ElementSegment*)elem)->data.size();
+  return (static_cast<ElementSegment*>(elem))->data.size();
 }
 const char* BinaryenElementSegmentGetData(BinaryenElementSegmentRef elem,
                                           BinaryenIndex dataId) {
-  const auto& data = ((ElementSegment*)elem)->data;
+  const auto& data = (static_cast<ElementSegment*>(elem))->data;
   if (data.size() <= dataId) {
     Fatal() << "invalid segment data id.";
+    WASM_UNREACHABLE("invalid id");
   }
   if (data[dataId]->is<RefNull>()) {
     return NULL;
@@ -5435,6 +5436,7 @@
     return get->func.str.data();
   } else {
     Fatal() << "invalid expression in segment data.";
+    WASM_UNREACHABLE("invalid expression");
   }
 }
 
@@ -5456,14 +5458,14 @@
   auto memory = std::make_unique<Memory>();
   memory->name = name ? name : "0";
   memory->initial = initial;
-  memory->max = int32_t(maximum); // Make sure -1 extends.
+  memory->max = static_cast<int32_t>(maximum); // Make sure -1 extends.
   memory->shared = shared;
   memory->addressType = memory64 ? Type::i64 : Type::i32;
   if (exportName) {
-    ((Module*)module)
+    (static_cast<Module*>(module))
       ->addExport(new Export(exportName, ExternalKind::Memory, memory->name));
   }
-  ((Module*)module)->removeDataSegments([&](DataSegment* curr) {
+  (static_cast<Module*>(module))->removeDataSegments([&](DataSegment* curr) {
     return true;
   });
   for (BinaryenIndex i = 0; i < numSegments; i++) {
@@ -5472,24 +5474,24 @@
     auto curr = Builder::makeDataSegment(name,
                                          memory->name,
                                          segmentPassives[i],
-                                         (Expression*)segmentOffsets[i],
+                                         reinterpret_cast<Expression**>(segmentOffsets)[i],
                                          segmentDatas[i],
                                          segmentSizes[i]);
     curr->hasExplicitName = explicitName;
-    ((Module*)module)->addDataSegment(std::move(curr));
+    (static_cast<Module*>(module))->addDataSegment(std::move(curr));
   }
-  ((Module*)module)->removeMemories([&](Memory* curr) { return true; });
-  ((Module*)module)->addMemory(std::move(memory));
+  (static_cast<Module*>(module))->removeMemories([&](Memory* curr) { return true; });
+  (static_cast<Module*>(module))->addMemory(std::move(memory));
 }
 
 // Memory segments
 
 uint32_t BinaryenGetNumMemorySegments(BinaryenModuleRef module) {
-  return ((Module*)module)->dataSegments.size();
+  return (static_cast<Module*>(module))->dataSegments.size();
 }
 uint32_t BinaryenGetMemorySegmentByteOffset(BinaryenModuleRef module,
                                             const char* segmentName) {
-  auto* wasm = (Module*)module;
+  auto* wasm = static_cast<Module*>(module);
   const auto* segment = wasm->getDataSegmentOrNull(Name(segmentName));
   if (segment == NULL) {
     Fatal() << "invalid segment name.";
@@ -5519,7 +5521,7 @@
   return 0;
 }
 bool BinaryenHasMemory(BinaryenModuleRef module) {
-  return !((Module*)module)->memories.empty();
+  return !(static_cast<Module*>(module))->memories.empty();
 }
 BinaryenIndex BinaryenMemoryGetInitial(BinaryenModuleRef module,
                                        const char* name) {
@@ -5527,7 +5529,7 @@
   if (name == nullptr && module->memories.size() == 1) {
     name = module->memories[0]->name.str.data();
   }
-  auto* memory = ((Module*)module)->getMemoryOrNull(name);
+  auto* memory = (static_cast<Module*>(module))->getMemoryOrNull(name);
   if (memory == nullptr) {
     Fatal() << "invalid memory '" << name << "'.";
   }
@@ -5538,7 +5540,7 @@
   if (name == nullptr && module->memories.size() == 1) {
     name = module->memories[0]->name.str.data();
   }
-  auto* memory = ((Module*)module)->getMemoryOrNull(name);
+  auto* memory = (static_cast<Module*>(module))->getMemoryOrNull(name);
   if (memory == nullptr) {
     Fatal() << "invalid memory '" << name << "'.";
   }
@@ -5549,7 +5551,7 @@
   if (name == nullptr && module->memories.size() == 1) {
     name = module->memories[0]->name.str.data();
   }
-  auto* memory = ((Module*)module)->getMemoryOrNull(name);
+  auto* memory = (static_cast<Module*>(module))->getMemoryOrNull(name);
   if (memory == nullptr) {
     Fatal() << "invalid memory '" << name << "'.";
   }
@@ -5561,7 +5563,7 @@
   if (name == nullptr && module->memories.size() == 1) {
     name = module->memories[0]->name.str.data();
   }
-  auto* memory = ((Module*)module)->getMemoryOrNull(name);
+  auto* memory = (static_cast<Module*>(module))->getMemoryOrNull(name);
   if (memory == nullptr) {
     Fatal() << "invalid memory '" << name << "'.";
   }
@@ -5577,7 +5579,7 @@
   if (name == nullptr && module->memories.size() == 1) {
     name = module->memories[0]->name.str.data();
   }
-  auto* memory = ((Module*)module)->getMemoryOrNull(name);
+  auto* memory = (static_cast<Module*>(module))->getMemoryOrNull(name);
   if (memory == nullptr) {
     Fatal() << "invalid memory '" << name << "'.";
   }
@@ -5592,7 +5594,7 @@
   if (name == nullptr && module->memories.size() == 1) {
     name = module->memories[0]->name.str.data();
   }
-  auto* memory = ((Module*)module)->getMemoryOrNull(name);
+  auto* memory = (static_cast<Module*>(module))->getMemoryOrNull(name);
   if (memory == nullptr) {
     Fatal() << "invalid memory '" << name << "'.";
   }
@@ -5603,7 +5605,7 @@
   if (name == nullptr && module->memories.size() == 1) {
     name = module->memories[0]->name.str.data();
   }
-  auto* memory = ((Module*)module)->getMemoryOrNull(name);
+  auto* memory = (static_cast<Module*>(module))->getMemoryOrNull(name);
   if (memory == nullptr) {
     Fatal() << "invalid memory '" << name << "'.";
   }
@@ -5611,7 +5613,7 @@
 }
 size_t BinaryenGetMemorySegmentByteLength(BinaryenModuleRef module,
                                           const char* segmentName) {
-  auto* wasm = (Module*)module;
+  auto* wasm = static_cast<Module*>(module);
   const auto* segment = wasm->getDataSegmentOrNull(Name(segmentName));
   if (segment == NULL) {
     Fatal() << "invalid segment name.";
@@ -5620,7 +5622,7 @@
 }
 bool BinaryenGetMemorySegmentPassive(BinaryenModuleRef module,
                                      const char* segmentName) {
-  auto* wasm = (Module*)module;
+  auto* wasm = static_cast<Module*>(module);
   const auto* segment = wasm->getDataSegmentOrNull(Name(segmentName));
   if (segment == NULL) {
     Fatal() << "invalid segment name.";
@@ -5630,7 +5632,7 @@
 void BinaryenCopyMemorySegmentData(BinaryenModuleRef module,
                                    const char* segmentName,
                                    char* buffer) {
-  auto* wasm = (Module*)module;
+  auto* wasm = static_cast<Module*>(module);
   const auto* segment = wasm->getDataSegmentOrNull(Name(segmentName));
   if (segment == NULL) {
     Fatal() << "invalid segment name.";
@@ -5644,13 +5646,13 @@
                             BinaryenExpressionRef segmentOffset,
                             const char* segmentData,
                             BinaryenIndex segmentSize) {
-  auto* wasm = (Module*)module;
+  auto* wasm = static_cast<Module*>(module);
   auto name =
     segmentName ? Name(segmentName) : Name::fromInt(wasm->dataSegments.size());
   auto curr = Builder::makeDataSegment(name,
                                        memoryName ? memoryName : "0",
                                        segmentPassive,
-                                       (Expression*)segmentOffset,
+                                       static_cast<Expression*>(segmentOffset),
                                        segmentData,
                                        segmentSize);
   curr->hasExplicitName = segmentName ? true : false;
@@ -5660,22 +5662,22 @@
 // Start function. One per module
 
 void BinaryenSetStart(BinaryenModuleRef module, BinaryenFunctionRef start) {
-  ((Module*)module)->addStart(((Function*)start)->name);
+  (static_cast<Module*>(module))->addStart((static_cast<Function*>(start))->name);
 }
 
 BinaryenFunctionRef BinaryenGetStart(BinaryenModuleRef module) {
-  return ((Module*)module)->getFunctionOrNull(((Module*)module)->start);
+  return (static_cast<Module*>(module))->getFunctionOrNull((static_cast<Module*>(module))->start);
 }
 
 // Features
 
 BinaryenFeatures BinaryenModuleGetFeatures(BinaryenModuleRef module) {
-  return ((Module*)module)->features.features;
+  return (static_cast<Module*>(module))->features.features;
 }
 
 void BinaryenModuleSetFeatures(BinaryenModuleRef module,
                                BinaryenFeatures features) {
-  ((Module*)module)->features.features = features;
+  (static_cast<Module*>(module))->features.features = features;
 }
 
 //
@@ -5692,15 +5694,15 @@
 }
 
 void BinaryenModulePrint(BinaryenModuleRef module) {
-  std::cout << *(Module*)module;
+  std::cout << *static_cast<Module*>(module);
 }
 
 void BinaryenModulePrintStackIR(BinaryenModuleRef module) {
-  wasm::printStackIR(std::cout, (Module*)module, globalPassOptions);
+  wasm::printStackIR(std::cout, static_cast<Module*>(module), globalPassOptions);
 }
 
 void BinaryenModulePrintAsmjs(BinaryenModuleRef module) {
-  auto* wasm = (Module*)module;
+  auto* wasm = static_cast<Module*>(module);
   Wasm2JSBuilder::Flags flags;
   Wasm2JSBuilder wasm2js(flags, globalPassOptions);
   auto asmjs = wasm2js.processWasm(wasm);
@@ -5714,18 +5716,18 @@
 }
 
 bool BinaryenModuleValidate(BinaryenModuleRef module) {
-  return WasmValidator().validate(*(Module*)module);
+  return WasmValidator().validate(*static_cast<Module*>(module));
 }
 
 void BinaryenModuleOptimize(BinaryenModuleRef module) {
-  PassRunner passRunner((Module*)module);
+  PassRunner passRunner(static_cast<Module*>(module));
   passRunner.options = globalPassOptions;
   passRunner.addDefaultOptimizationPasses();
   passRunner.run();
 }
 
 void BinaryenModuleUpdateMaps(BinaryenModuleRef module) {
-  ((Module*)module)->updateMaps();
+  (static_cast<Module*>(module))->updateMaps();
 }
 
 int BinaryenGetOptimizeLevel(void) { return globalPassOptions.optimizeLevel; }
@@ -5869,7 +5871,7 @@
 void BinaryenModuleRunPasses(BinaryenModuleRef module,
                              const char** passes,
                              BinaryenIndex numPasses) {
-  PassRunner passRunner((Module*)module);
+  PassRunner passRunner(static_cast<Module*>(module));
   passRunner.options = globalPassOptions;
   for (BinaryenIndex i = 0; i < numPasses; i++) {
     passRunner.add(passes[i],
@@ -5887,7 +5889,7 @@
                                        char* sourceMap,
                                        size_t sourceMapSize) {
   BufferWithRandomAccess buffer;
-  WasmBinaryWriter writer((Module*)module, buffer, globalPassOptions);
+  WasmBinaryWriter writer(static_cast<Module*>(module), buffer, globalPassOptions);
   writer.setNamesSection(globalPassOptions.debugInfo);
   std::ostringstream os;
   if (sourceMapUrl) {
@@ -5907,7 +5909,7 @@
 
 size_t
 BinaryenModuleWrite(BinaryenModuleRef module, char* output, size_t outputSize) {
-  return writeModule((Module*)module, output, outputSize, nullptr, nullptr, 0)
+  return writeModule(static_cast<Module*>(module), output, outputSize, nullptr, nullptr, 0)
     .outputBytes;
 }
 
@@ -5917,7 +5919,7 @@
   // use a stringstream as an std::ostream. Extract the std::string
   // representation, and then store in the output.
   std::stringstream ss;
-  ss << *(Module*)module;
+  ss << *static_cast<Module*>(module);
 
   const auto temp = ss.str();
   const auto ctemp = temp.c_str();
@@ -5932,7 +5934,7 @@
   // use a stringstream as an std::ostream. Extract the std::string
   // representation, and then store in the output.
   std::stringstream ss;
-  wasm::printStackIR(ss, (Module*)module, globalPassOptions);
+  wasm::printStackIR(ss, static_cast<Module*>(module), globalPassOptions);
 
   const auto temp = ss.str();
   const auto ctemp = temp.c_str();
@@ -5950,14 +5952,14 @@
   assert(url);
   assert(sourceMap);
   return writeModule(
-    (Module*)module, output, outputSize, url, sourceMap, sourceMapSize);
+    static_cast<Module*>(module), output, outputSize, url, sourceMap, sourceMapSize);
 }
 
 BinaryenModuleAllocateAndWriteResult
 BinaryenModuleAllocateAndWrite(BinaryenModuleRef module,
                                const char* sourceMapUrl) {
   BufferWithRandomAccess buffer;
-  WasmBinaryWriter writer((Module*)module, buffer, globalPassOptions);
+  WasmBinaryWriter writer(static_cast<Module*>(module), buffer, globalPassOptions);
   writer.setNamesSection(globalPassOptions.debugInfo);
   std::ostringstream os;
   if (sourceMapUrl) {
@@ -5970,7 +5972,7 @@
   if (sourceMapUrl) {
     auto str = os.str();
     const size_t len = str.length() + 1;
-    sourceMap = (char*)malloc(len);
+    sourceMap = static_cast<char*>(malloc(len));
     std::copy_n(str.c_str(), len, sourceMap);
   }
   return {binary, buffer.size(), sourceMap};
@@ -5981,12 +5983,12 @@
   bool colors = Colors::isEnabled();
 
   Colors::setEnabled(false); // do not use colors for writing
-  os << *(Module*)module;
+  os << *static_cast<Module*>(module);
   Colors::setEnabled(colors); // restore colors state
 
   auto str = os.str();
   const size_t len = str.length() + 1;
-  char* output = (char*)malloc(len);
+  char* output = static_cast<char*>(malloc(len));
   std::copy_n(str.c_str(), len, output);
   return output;
 }
@@ -5996,12 +5998,12 @@
   bool colors = Colors::isEnabled();
 
   Colors::setEnabled(false); // do not use colors for writing
-  wasm::printStackIR(os, (Module*)module, globalPassOptions);
+  wasm::printStackIR(os, static_cast<Module*>(module), globalPassOptions);
   Colors::setEnabled(colors); // restore colors state
 
   auto str = os.str();
   const size_t len = str.length() + 1;
-  char* output = (char*)malloc(len);
+  char* output = static_cast<char*>(malloc(len));
   std::copy_n(str.c_str(), len, output);
   return output;
 }
@@ -6032,13 +6034,13 @@
 
 void BinaryenModuleInterpret(BinaryenModuleRef module) {
   ShellExternalInterface interface;
-  ModuleRunner instance(*(Module*)module, &interface, {});
+  ModuleRunner instance(*static_cast<Module*>(module), &interface, {});
   instance.instantiate();
 }
 
 BinaryenIndex BinaryenModuleAddDebugInfoFileName(BinaryenModuleRef module,
                                                  const char* filename) {
-  auto& debugInfoFileNames = ((Module*)module)->debugInfoFileNames;
+  auto& debugInfoFileNames = (static_cast<Module*>(module))->debugInfoFileNames;
   BinaryenIndex index = debugInfoFileNames.size();
   debugInfoFileNames.push_back(filename);
   return index;
@@ -6046,7 +6048,7 @@
 
 const char* BinaryenModuleGetDebugInfoFileName(BinaryenModuleRef module,
                                                BinaryenIndex index) {
-  const auto& debugInfoFileNames = ((Module*)module)->debugInfoFileNames;
+  const auto& debugInfoFileNames = (static_cast<Module*>(module))->debugInfoFileNames;
   return index < debugInfoFileNames.size()
            ? debugInfoFileNames.at(index).c_str()
            : nullptr;
@@ -6059,69 +6061,69 @@
 // TODO: add BinaryenFunctionGetType
 
 const char* BinaryenFunctionGetName(BinaryenFunctionRef func) {
-  return ((Function*)func)->name.str.data();
+  return (static_cast<Function*>(func))->name.str.data();
 }
 BinaryenType BinaryenFunctionGetParams(BinaryenFunctionRef func) {
-  return ((Function*)func)->getParams().getID();
+  return (static_cast<Function*>(func))->getParams().getID();
 }
 BinaryenType BinaryenFunctionGetResults(BinaryenFunctionRef func) {
-  return ((Function*)func)->getResults().getID();
+  return (static_cast<Function*>(func))->getResults().getID();
 }
 BinaryenIndex BinaryenFunctionGetNumVars(BinaryenFunctionRef func) {
-  return ((Function*)func)->vars.size();
+  return (static_cast<Function*>(func))->vars.size();
 }
 BinaryenType BinaryenFunctionGetVar(BinaryenFunctionRef func,
                                     BinaryenIndex index) {
-  const auto& vars = ((Function*)func)->vars;
+  const auto& vars = (static_cast<Function*>(func))->vars;
   assert(index < vars.size());
   return vars[index].getID();
 }
 BinaryenIndex BinaryenFunctionAddVar(BinaryenFunctionRef func,
                                      BinaryenType type) {
-  return Builder::addVar((Function*)func, (Type)type);
+  return Builder::addVar(static_cast<Function*>(func), (Type)type);
 }
 BinaryenIndex BinaryenFunctionGetNumLocals(BinaryenFunctionRef func) {
-  return ((Function*)func)->getNumLocals();
+  return (static_cast<Function*>(func))->getNumLocals();
 }
 bool BinaryenFunctionHasLocalName(BinaryenFunctionRef func,
                                   BinaryenIndex index) {
-  return ((Function*)func)->hasLocalName(index);
+  return (static_cast<Function*>(func))->hasLocalName(index);
 }
 const char* BinaryenFunctionGetLocalName(BinaryenFunctionRef func,
                                          BinaryenIndex index) {
-  return ((Function*)func)->getLocalName(index).str.data();
+  return (static_cast<Function*>(func))->getLocalName(index).str.data();
 }
 void BinaryenFunctionSetLocalName(BinaryenFunctionRef func,
                                   BinaryenIndex index,
                                   const char* name) {
-  ((Function*)func)->setLocalName(index, name);
+  (static_cast<Function*>(func))->setLocalName(index, name);
 }
 BinaryenExpressionRef BinaryenFunctionGetBody(BinaryenFunctionRef func) {
-  return ((Function*)func)->body;
+  return (static_cast<Function*>(func))->body;
 }
 void BinaryenFunctionSetBody(BinaryenFunctionRef func,
                              BinaryenExpressionRef body) {
   assert(body);
-  ((Function*)func)->body = (Expression*)body;
+  (static_cast<Function*>(func))->body = static_cast<Expression*>(body);
 }
 BinaryenHeapType BinaryenFunctionGetType(BinaryenFunctionRef func) {
-  return ((Function*)func)->type.getHeapType().getID();
+  return (static_cast<Function*>(func))->type.getHeapType().getID();
 }
 void BinaryenFunctionSetType(BinaryenFunctionRef func, BinaryenHeapType type) {
-  ((Function*)func)->type = Type(HeapType(type), NonNullable, Exact);
+  (static_cast<Function*>(func))->type = Type(HeapType(type), NonNullable, Exact);
 }
 void BinaryenFunctionOptimize(BinaryenFunctionRef func,
                               BinaryenModuleRef module) {
-  PassRunner passRunner((Module*)module);
+  PassRunner passRunner(static_cast<Module*>(module));
   passRunner.options = globalPassOptions;
   passRunner.addDefaultFunctionOptimizationPasses();
-  passRunner.runOnFunction((Function*)func);
+  passRunner.runOnFunction(static_cast<Function*>(func));
 }
 void BinaryenFunctionRunPasses(BinaryenFunctionRef func,
                                BinaryenModuleRef module,
                                const char** passes,
                                BinaryenIndex numPasses) {
-  PassRunner passRunner((Module*)module);
+  PassRunner passRunner(static_cast<Module*>(module));
   passRunner.options = globalPassOptions;
   for (BinaryenIndex i = 0; i < numPasses; i++) {
     passRunner.add(passes[i],
@@ -6129,7 +6131,7 @@
                      ? globalPassOptions.arguments[passes[i]]
                      : std::optional<std::string>());
   }
-  passRunner.runOnFunction((Function*)func);
+  passRunner.runOnFunction(static_cast<Function*>(func));
 }
 void BinaryenFunctionSetDebugLocation(BinaryenFunctionRef func,
                                       BinaryenExpressionRef expr,
@@ -6140,7 +6142,7 @@
   loc.fileIndex = fileIndex;
   loc.lineNumber = lineNumber;
   loc.columnNumber = columnNumber;
-  ((Function*)func)->debugLocations[(Expression*)expr] = loc;
+  (static_cast<Function*>(func))->debugLocations[static_cast<Expression*>(expr)] = loc;
 }
 
 //
@@ -6148,52 +6150,52 @@
 //
 
 const char* BinaryenTableGetName(BinaryenTableRef table) {
-  return ((Table*)table)->name.str.data();
+  return (static_cast<Table*>(table))->name.str.data();
 }
 void BinaryenTableSetName(BinaryenTableRef table, const char* name) {
-  ((Table*)table)->name = name;
+  (static_cast<Table*>(table))->name = name;
 }
 BinaryenIndex BinaryenTableGetInitial(BinaryenTableRef table) {
-  return ((Table*)table)->initial;
+  return (static_cast<Table*>(table))->initial;
 }
 void BinaryenTableSetInitial(BinaryenTableRef table, BinaryenIndex initial) {
-  ((Table*)table)->initial = initial;
+  (static_cast<Table*>(table))->initial = initial;
 }
 bool BinaryenTableHasMax(BinaryenTableRef table) {
-  return ((Table*)table)->hasMax();
+  return (static_cast<Table*>(table))->hasMax();
 }
 BinaryenIndex BinaryenTableGetMax(BinaryenTableRef table) {
-  return ((Table*)table)->max;
+  return (static_cast<Table*>(table))->max;
 }
 void BinaryenTableSetMax(BinaryenTableRef table, BinaryenIndex max) {
-  ((Table*)table)->max = max;
+  (static_cast<Table*>(table))->max = max;
 }
 BinaryenType BinaryenTableGetType(BinaryenTableRef table) {
-  return ((Table*)table)->type.getID();
+  return (static_cast<Table*>(table))->type.getID();
 }
 void BinaryenTableSetType(BinaryenTableRef table, BinaryenType tableType) {
-  ((Table*)table)->type = Type(tableType);
+  (static_cast<Table*>(table))->type = Type(tableType);
 }
 
 //
 // =========== ElementSegment operations ===========
 //
 const char* BinaryenElementSegmentGetName(BinaryenElementSegmentRef elem) {
-  return ((ElementSegment*)elem)->name.str.data();
+  return (static_cast<ElementSegment*>(elem))->name.str.data();
 }
 void BinaryenElementSegmentSetName(BinaryenElementSegmentRef elem,
                                    const char* name) {
-  ((ElementSegment*)elem)->name = name;
+  (static_cast<ElementSegment*>(elem))->name = name;
 }
 const char* BinaryenElementSegmentGetTable(BinaryenElementSegmentRef elem) {
-  return ((ElementSegment*)elem)->table.str.data();
+  return (static_cast<ElementSegment*>(elem))->table.str.data();
 }
 void BinaryenElementSegmentSetTable(BinaryenElementSegmentRef elem,
                                     const char* table) {
-  ((ElementSegment*)elem)->table = table;
+  (static_cast<ElementSegment*>(elem))->table = table;
 }
 bool BinaryenElementSegmentIsPassive(BinaryenElementSegmentRef elem) {
-  return ((ElementSegment*)elem)->table.isNull();
+  return (static_cast<ElementSegment*>(elem))->table.isNull();
 }
 
 //
@@ -6201,16 +6203,16 @@
 //
 
 const char* BinaryenGlobalGetName(BinaryenGlobalRef global) {
-  return ((Global*)global)->name.str.data();
+  return (static_cast<Global*>(global))->name.str.data();
 }
 BinaryenType BinaryenGlobalGetType(BinaryenGlobalRef global) {
-  return ((Global*)global)->type.getID();
+  return (static_cast<Global*>(global))->type.getID();
 }
 bool BinaryenGlobalIsMutable(BinaryenGlobalRef global) {
-  return ((Global*)global)->mutable_;
+  return (static_cast<Global*>(global))->mutable_;
 }
 BinaryenExpressionRef BinaryenGlobalGetInitExpr(BinaryenGlobalRef global) {
-  return ((Global*)global)->init;
+  return (static_cast<Global*>(global))->init;
 }
 
 //
@@ -6218,14 +6220,14 @@
 //
 
 const char* BinaryenTagGetName(BinaryenTagRef tag) {
-  return ((Tag*)tag)->name.str.data();
+  return (static_cast<Tag*>(tag))->name.str.data();
 }
 BinaryenType BinaryenTagGetParams(BinaryenTagRef tag) {
-  return ((Tag*)tag)->params().getID();
+  return (static_cast<Tag*>(tag))->params().getID();
 }
 
 BinaryenType BinaryenTagGetResults(BinaryenTagRef tag) {
-  return ((Tag*)tag)->results().getID();
+  return (static_cast<Tag*>(tag))->results().getID();
 }
 
 //
@@ -6233,7 +6235,7 @@
 //
 
 const char* BinaryenFunctionImportGetModule(BinaryenFunctionRef import) {
-  auto* func = (Function*)import;
+  auto* func = static_cast<Function*>(import);
   if (func->imported()) {
     return func->module.str.data();
   } else {
@@ -6241,7 +6243,7 @@
   }
 }
 const char* BinaryenTableImportGetModule(BinaryenTableRef import) {
-  auto* table = (Table*)import;
+  auto* table = static_cast<Table*>(import);
   if (table->imported()) {
     return table->module.str.data();
   } else {
@@ -6249,7 +6251,7 @@
   }
 }
 const char* BinaryenGlobalImportGetModule(BinaryenGlobalRef import) {
-  auto* global = (Global*)import;
+  auto* global = static_cast<Global*>(import);
   if (global->imported()) {
     return global->module.str.data();
   } else {
@@ -6257,7 +6259,7 @@
   }
 }
 const char* BinaryenTagImportGetModule(BinaryenTagRef import) {
-  auto* tag = (Tag*)import;
+  auto* tag = static_cast<Tag*>(import);
   if (tag->imported()) {
     return tag->module.str.data();
   } else {
@@ -6265,7 +6267,7 @@
   }
 }
 const char* BinaryenFunctionImportGetBase(BinaryenFunctionRef import) {
-  auto* func = (Function*)import;
+  auto* func = static_cast<Function*>(import);
   if (func->imported()) {
     return func->base.str.data();
   } else {
@@ -6273,7 +6275,7 @@
   }
 }
 const char* BinaryenTableImportGetBase(BinaryenTableRef import) {
-  auto* table = (Table*)import;
+  auto* table = static_cast<Table*>(import);
   if (table->imported()) {
     return table->base.str.data();
   } else {
@@ -6281,7 +6283,7 @@
   }
 }
 const char* BinaryenGlobalImportGetBase(BinaryenGlobalRef import) {
-  auto* global = (Global*)import;
+  auto* global = static_cast<Global*>(import);
   if (global->imported()) {
     return global->base.str.data();
   } else {
@@ -6289,7 +6291,7 @@
   }
 }
 const char* BinaryenTagImportGetBase(BinaryenTagRef import) {
-  auto* tag = (Tag*)import;
+  auto* tag = static_cast<Tag*>(import);
   if (tag->imported()) {
     return tag->base.str.data();
   } else {
@@ -6302,13 +6304,13 @@
 //
 
 BinaryenExternalKind BinaryenExportGetKind(BinaryenExportRef export_) {
-  return BinaryenExternalKind(((Export*)export_)->kind);
+  return BinaryenExternalKind((static_cast<Export*>(export_))->kind);
 }
 const char* BinaryenExportGetName(BinaryenExportRef export_) {
-  return ((Export*)export_)->name.str.data();
+  return (static_cast<Export*>(export_))->name.str.data();
 }
 const char* BinaryenExportGetValue(BinaryenExportRef export_) {
-  return ((Export*)export_)->getInternalName()->str.data();
+  return (static_cast<Export*>(export_))->getInternalName()->str.data();
 }
 
 //
@@ -6322,7 +6324,7 @@
   wasm::CustomSection customSection;
   customSection.name = name;
   customSection.data = std::vector<char>(contents, contents + contentsSize);
-  ((Module*)module)->customSections.push_back(customSection);
+  (static_cast<Module*>(module))->customSections.push_back(customSection);
 }
 
 //
@@ -6396,7 +6398,7 @@
 
 BinaryenSideEffects BinaryenExpressionGetSideEffects(BinaryenExpressionRef expr,
                                                      BinaryenModuleRef module) {
-  return EffectAnalyzer(globalPassOptions, *(Module*)module, (Expression*)expr)
+  return EffectAnalyzer(globalPassOptions, *static_cast<Module*>(module), static_cast<Expression*>(expr))
     .getSideEffects();
 }
 
@@ -6405,13 +6407,13 @@
 //
 
 RelooperRef RelooperCreate(BinaryenModuleRef module) {
-  return RelooperRef(new CFG::Relooper((Module*)module));
+  return RelooperRef(new CFG::Relooper(static_cast<Module*>(module)));
 }
 
 RelooperBlockRef RelooperAddBlock(RelooperRef relooper,
                                   BinaryenExpressionRef code) {
   return RelooperBlockRef(
-    ((CFG::Relooper*)relooper)->AddBlock((Expression*)code));
+    ((CFG::Relooper*)relooper)->AddBlock(static_cast<Expression*>(code)));
 }
 
 void RelooperAddBranch(RelooperBlockRef from,
@@ -6419,7 +6421,7 @@
                        BinaryenExpressionRef condition,
                        BinaryenExpressionRef code) {
   ((CFG::Block*)from)
-    ->AddBranchTo((CFG::Block*)to, (Expression*)condition, (Expression*)code);
+    ->AddBranchTo((CFG::Block*)to, static_cast<Expression*>(condition), static_cast<Expression*>(code));
 }
 
 RelooperBlockRef RelooperAddBlockWithSwitch(RelooperRef relooper,
@@ -6427,7 +6429,7 @@
                                             BinaryenExpressionRef condition) {
   return RelooperBlockRef(
     ((CFG::Relooper*)relooper)
-      ->AddBlock((Expression*)code, (Expression*)condition));
+      ->AddBlock(static_cast<Expression*>(code), static_cast<Expression*>(condition)));
 }
 
 void RelooperAddBranchForSwitch(RelooperBlockRef from,
@@ -6440,7 +6442,7 @@
     values.push_back(indexes[i]);
   }
   ((CFG::Block*)from)
-    ->AddSwitchBranchTo((CFG::Block*)to, std::move(values), (Expression*)code);
+    ->AddSwitchBranchTo((CFG::Block*)to, std::move(values), static_cast<Expression*>(code));
 }
 
 BinaryenExpressionRef RelooperRenderAndDispose(RelooperRef relooper,
@@ -6489,13 +6491,13 @@
                                            BinaryenIndex maxDepth,
                                            BinaryenIndex maxLoopIterations) {
   return static_cast<ExpressionRunnerRef>(
-    new CExpressionRunner((Module*)module, flags, maxDepth, maxLoopIterations));
+    new CExpressionRunner(static_cast<Module*>(module), flags, maxDepth, maxLoopIterations));
 }
 
 bool ExpressionRunnerSetLocalValue(ExpressionRunnerRef runner,
                                    BinaryenIndex index,
                                    BinaryenExpressionRef value) {
-  auto* R = (CExpressionRunner*)runner;
+  auto* R = static_cast<CExpressionRunner*>(runner);
   auto setFlow = R->visit(value);
   if (!setFlow.breaking()) {
     R->setLocalValue(index, setFlow.values);
@@ -6507,7 +6509,7 @@
 bool ExpressionRunnerSetGlobalValue(ExpressionRunnerRef runner,
                                     const char* name,
                                     BinaryenExpressionRef value) {
-  auto* R = (CExpressionRunner*)runner;
+  auto* R = static_cast<CExpressionRunner*>(runner);
   auto setFlow = R->visit(value);
   if (!setFlow.breaking()) {
     R->setGlobalValue(name, setFlow.values);
@@ -6519,7 +6521,7 @@
 BinaryenExpressionRef
 ExpressionRunnerRunAndDispose(ExpressionRunnerRef runner,
                               BinaryenExpressionRef expr) {
-  auto* R = (CExpressionRunner*)runner;
+  auto* R = static_cast<CExpressionRunner*>(runner);
   Expression* ret = nullptr;
   try {
     auto flow = R->visit(expr);
@@ -6557,16 +6559,16 @@
   return static_cast<TypeBuilderRef>(new TypeBuilder(size));
 }
 void TypeBuilderGrow(TypeBuilderRef builder, BinaryenIndex count) {
-  ((TypeBuilder*)builder)->grow(count);
+  (static_cast<TypeBuilder*>(builder))->grow(count);
 }
 BinaryenIndex TypeBuilderGetSize(TypeBuilderRef builder) {
-  return ((TypeBuilder*)builder)->size();
+  return (static_cast<TypeBuilder*>(builder))->size();
 }
 void TypeBuilderSetSignatureType(TypeBuilderRef builder,
                                  BinaryenIndex index,
                                  BinaryenType paramTypes,
                                  BinaryenType resultTypes) {
-  ((TypeBuilder*)builder)
+  (static_cast<TypeBuilder*>(builder))
     ->setHeapType(index, Signature(Type(paramTypes), Type(resultTypes)));
 }
 void TypeBuilderSetStructType(TypeBuilderRef builder,
@@ -6575,7 +6577,7 @@
                               BinaryenPackedType* fieldPackedTypes,
                               bool* fieldMutables,
                               int numFields) {
-  auto* B = (TypeBuilder*)builder;
+  auto* B = static_cast<TypeBuilder*>(builder);
   FieldList fields;
   for (int cur = 0; cur < numFields; ++cur) {
     Field field(Type(fieldTypes[cur]),
@@ -6595,7 +6597,7 @@
                              BinaryenType elementType,
                              BinaryenPackedType elementPackedType,
                              int elementMutable) {
-  auto* B = (TypeBuilder*)builder;
+  auto* B = static_cast<TypeBuilder*>(builder);
   Field element(Type(elementType),
                 elementMutable ? Mutability::Mutable : Mutability::Immutable);
   if (element.type == Type::i32) {
@@ -6607,7 +6609,7 @@
 }
 BinaryenHeapType TypeBuilderGetTempHeapType(TypeBuilderRef builder,
                                             BinaryenIndex index) {
-  return ((TypeBuilder*)builder)->getTempHeapType(index).getID();
+  return (static_cast<TypeBuilder*>(builder))->getTempHeapType(index).getID();
 }
 BinaryenType TypeBuilderGetTempTupleType(TypeBuilderRef builder,
                                          BinaryenType* types,
@@ -6616,33 +6618,33 @@
   for (BinaryenIndex cur = 0; cur < numTypes; ++cur) {
     typeList[cur] = Type(types[cur]);
   }
-  return ((TypeBuilder*)builder)->getTempTupleType(Tuple(typeList)).getID();
+  return (static_cast<TypeBuilder*>(builder))->getTempTupleType(Tuple(typeList)).getID();
 }
 BinaryenType TypeBuilderGetTempRefType(TypeBuilderRef builder,
                                        BinaryenHeapType heapType,
                                        int nullable) {
-  return ((TypeBuilder*)builder)
+  return (static_cast<TypeBuilder*>(builder))
     ->getTempRefType(HeapType(heapType), nullable ? Nullable : NonNullable)
     .getID();
 }
 void TypeBuilderSetSubType(TypeBuilderRef builder,
                            BinaryenIndex index,
                            BinaryenHeapType superType) {
-  ((TypeBuilder*)builder)->setSubType(index, HeapType(superType));
+  (static_cast<TypeBuilder*>(builder))->setSubType(index, HeapType(superType));
 }
 void TypeBuilderSetOpen(TypeBuilderRef builder, BinaryenIndex index) {
-  ((TypeBuilder*)builder)->setOpen(index);
+  (static_cast<TypeBuilder*>(builder))->setOpen(index);
 }
 void TypeBuilderCreateRecGroup(TypeBuilderRef builder,
                                BinaryenIndex index,
                                BinaryenIndex length) {
-  ((TypeBuilder*)builder)->createRecGroup(index, length);
+  (static_cast<TypeBuilder*>(builder))->createRecGroup(index, length);
 }
 bool TypeBuilderBuildAndDispose(TypeBuilderRef builder,
                                 BinaryenHeapType* heapTypes,
                                 BinaryenIndex* errorIndex,
                                 TypeBuilderErrorReason* errorReason) {
-  auto* B = (TypeBuilder*)builder;
+  auto* B = static_cast<TypeBuilder*>(builder);
   auto result = B->build();
   if (auto err = result.getError()) {
     if (errorIndex) {
@@ -6665,13 +6667,13 @@
 void BinaryenModuleSetTypeName(BinaryenModuleRef module,
                                BinaryenHeapType heapType,
                                const char* name) {
-  ((Module*)module)->typeNames[HeapType(heapType)].name = name;
+  (static_cast<Module*>(module))->typeNames[HeapType(heapType)].name = name;
 }
 void BinaryenModuleSetFieldName(BinaryenModuleRef module,
                                 BinaryenHeapType heapType,
                                 BinaryenIndex index,
                                 const char* name) {
-  ((Module*)module)->typeNames[HeapType(heapType)].fieldNames[index] = name;
+  (static_cast<Module*>(module))->typeNames[HeapType(heapType)].fieldNames[index] = name;
 }
 
 //
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 1fc0134..4a55212 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -1656,9 +1656,9 @@
 // Sets the 32-bit float value of a `f32.const` expression.
 BINARYEN_API void BinaryenConstSetValueF32(BinaryenExpressionRef expr,
                                            float value);
-// Gets the 64-bit float (double) value of a `f64.const` expression.
+// Gets the 64-bit float static_cast<double>(value) of a `f64.const` expression.
 BINARYEN_API double BinaryenConstGetValueF64(BinaryenExpressionRef expr);
-// Sets the 64-bit float (double) value of a `f64.const` expression.
+// Sets the 64-bit float static_cast<double>(value) of a `f64.const` expression.
 BINARYEN_API void BinaryenConstSetValueF64(BinaryenExpressionRef expr,
                                            double value);
 // Reads the 128-bit vector value of a `v128.const` expression.
diff --git a/src/cfg/Relooper.cpp b/src/cfg/Relooper.cpp
index c681094..f402f71 100644
--- a/src/cfg/Relooper.cpp
+++ b/src/cfg/Relooper.cpp
@@ -1013,12 +1013,12 @@
   // for the blocks.
   size_t Hash(Block* Curr) {
     auto digest = wasm::ExpressionAnalyzer::hash(Curr->Code);
-    wasm::rehash(digest, uint8_t(1));
+    wasm::rehash(digest, static_cast<uint8_t>(1));
     if (Curr->SwitchCondition) {
       wasm::hash_combine(digest,
                          wasm::ExpressionAnalyzer::hash(Curr->SwitchCondition));
     }
-    wasm::rehash(digest, uint8_t(2));
+    wasm::rehash(digest, static_cast<uint8_t>(2));
     for (auto& [CurrBlock, CurrBranch] : Curr->BranchesOut) {
       // Hash the Block* as a pointer TODO: full hash?
       wasm::rehash(digest, reinterpret_cast<size_t>(CurrBlock));
@@ -1042,7 +1042,7 @@
                            wasm::ExpressionAnalyzer::hash(Curr->Condition));
       }
     }
-    wasm::rehash(digest, uint8_t(1));
+    wasm::rehash(digest, static_cast<uint8_t>(1));
     if (Curr->Code) {
       wasm::hash_combine(digest, wasm::ExpressionAnalyzer::hash(Curr->Code));
     }
diff --git a/src/cfg/Relooper.h b/src/cfg/Relooper.h
index 28a1903..e306495 100644
--- a/src/cfg/Relooper.h
+++ b/src/cfg/Relooper.h
@@ -55,11 +55,11 @@
     return makeLocalGet(labelHelper, wasm::Type::i32);
   }
   wasm::LocalSet* makeSetLabel(wasm::Index value) {
-    return makeLocalSet(labelHelper, makeConst(wasm::Literal(int32_t(value))));
+    return makeLocalSet(labelHelper, makeConst(wasm::Literal(static_cast<int32_t>(value))));
   }
   wasm::Binary* makeCheckLabel(wasm::Index value) {
     return makeBinary(
-      wasm::EqInt32, makeGetLabel(), makeConst(wasm::Literal(int32_t(value))));
+      wasm::EqInt32, makeGetLabel(), makeConst(wasm::Literal(static_cast<int32_t>(value))));
   }
 
   // breaks are on blocks, as they can be specific, we make one wasm block per
@@ -225,13 +225,13 @@
   virtual wasm::Expression* Render(RelooperBuilder& Builder, bool InLoop) = 0;
 
   static SimpleShape* IsSimple(Shape* It) {
-    return It && It->Type == Simple ? (SimpleShape*)It : NULL;
+    return It && It->Type == Simple ? reinterpret_cast<SimpleShape*>(It) : NULL;
   }
   static MultipleShape* IsMultiple(Shape* It) {
-    return It && It->Type == Multiple ? (MultipleShape*)It : NULL;
+    return It && It->Type == Multiple ? reinterpret_cast<MultipleShape*>(It) : NULL;
   }
   static LoopShape* IsLoop(Shape* It) {
-    return It && It->Type == Loop ? (LoopShape*)It : NULL;
+    return It && It->Type == Loop ? reinterpret_cast<LoopShape*>(It) : NULL;
   }
 };
 
diff --git a/src/cfg/cfg-traversal.h b/src/cfg/cfg-traversal.h
index 67e34f0..3963442 100644
--- a/src/cfg/cfg-traversal.h
+++ b/src/cfg/cfg-traversal.h
@@ -114,7 +114,7 @@
   std::vector<Index> catchIndexStack;
 
   BasicBlock* startBasicBlock() {
-    currBasicBlock = ((SubType*)this)->makeBasicBlock();
+    currBasicBlock = (static_cast<SubType*>(this))->makeBasicBlock();
     basicBlocks.push_back(std::unique_ptr<BasicBlock>(currBasicBlock));
     return currBasicBlock;
   }
diff --git a/src/cfg/liveness-traversal.h b/src/cfg/liveness-traversal.h
index 650ee4f..4a68358 100644
--- a/src/cfg/liveness-traversal.h
+++ b/src/cfg/liveness-traversal.h
@@ -279,7 +279,7 @@
   void scanLivenessThroughActions(std::vector<LivenessAction>& actions,
                                   SetOfLocals& live) {
     // move towards the front
-    for (int i = int(actions.size()) - 1; i >= 0; i--) {
+    for (int i = static_cast<int>(actions.size()) - 1; i >= 0; i--) {
       auto& action = actions[i];
       if (action.isGet()) {
         live.insert(action.index);
@@ -293,7 +293,7 @@
     if (j > i) {
       std::swap(i, j);
     }
-    copies.set(i, j, std::min(copies.get(i, j), uint8_t(254)) + 1);
+    copies.set(i, j, std::min(copies.get(i, j), static_cast<uint8_t>(254)) + 1);
     totalCopies[i]++;
     totalCopies[j]++;
   }
diff --git a/src/emscripten-optimizer/simple_ast.h b/src/emscripten-optimizer/simple_ast.h
index a2c541e..e6bdad5 100644
--- a/src/emscripten-optimizer/simple_ast.h
+++ b/src/emscripten-optimizer/simple_ast.h
@@ -258,7 +258,7 @@
   int32_t getInteger() { // convenience function to get a known integer
     assert(wasm::isInteger(getNumber()));
     int32_t ret = getNumber();
-    assert(double(ret) == getNumber()); // no loss in conversion
+    assert(static_cast<double>(ret) == getNumber()); // no loss in conversion
     return ret;
   }
 
@@ -576,15 +576,15 @@
     if (size >= used + safety) {
       return;
     }
-    size = std::max((size_t)1024, size * 2) + safety;
+    size = std::max(static_cast<size_t>(1024), size * 2) + safety;
     if (!buffer) {
-      buffer = (char*)malloc(size);
+      buffer = static_cast<char*>(malloc(size));
       if (!buffer) {
         errv("Out of memory allocating %zd bytes for output buffer!", size);
         abort();
       }
     } else {
-      char* buf = (char*)realloc(buffer, size);
+      char* buf = static_cast<char*>(realloc(buffer, size));
       if (!buf) {
         free(buffer);
         errv("Out of memory allocating %zd bytes for output buffer!", size);
@@ -985,7 +985,7 @@
           if (asHex) {
             unsigned long long tempULL;
             sscanf(buffer, "%llx", &tempULL);
-            temp = (double)tempULL;
+            temp = static_cast<double>(tempULL);
           } else {
             sscanf(buffer, "%lf", &temp);
           }
@@ -1610,8 +1610,8 @@
   static Ref makeDouble(double num) {
     return &arena.alloc<Value>()->setNumber(num);
   }
-  static Ref makeInt(uint32_t num) { return makeDouble(double(num)); }
-  static Ref makeInt(int32_t num) { return makeDouble(double(num)); }
+  static Ref makeInt(uint32_t num) { return makeDouble(static_cast<double>(num)); }
+  static Ref makeInt(int32_t num) { return makeDouble(static_cast<double>(num)); }
   static Ref makeNum(double num) { return makeDouble(num); }
 
   static Ref makeUnary(IString op, Ref value) {
diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp
index a6f11a7..b0b1142 100644
--- a/src/ir/ExpressionAnalyzer.cpp
+++ b/src/ir/ExpressionAnalyzer.cpp
@@ -29,7 +29,7 @@
 // For example, if the parent is a block and the node is before the last
 // position, it is not used.
 bool ExpressionAnalyzer::isResultUsed(ExpressionStack& stack, Function* func) {
-  for (int i = int(stack.size()) - 2; i >= 0; i--) {
+  for (int i = static_cast<int>(stack.size()) - 2; i >= 0; i--) {
     auto* curr = stack[i];
     auto* above = stack[i + 1];
     // only if and block can drop values (pre-drop expression was added) FIXME
@@ -65,7 +65,7 @@
 
 // Checks if a value is dropped.
 bool ExpressionAnalyzer::isResultDropped(ExpressionStack& stack) {
-  for (int i = int(stack.size()) - 2; i >= 0; i--) {
+  for (int i = static_cast<int>(stack.size()) - 2; i >= 0; i--) {
     auto* curr = stack[i];
     auto* above = stack[i + 1];
     if (curr->is<Block>()) {
diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp
index 51ed755..fc9de61 100644
--- a/src/ir/ExpressionManipulator.cpp
+++ b/src/ir/ExpressionManipulator.cpp
@@ -65,7 +65,7 @@
 // Iterate in reverse order here so we visit children in normal order.
 #define DELEGATE_FIELD_CHILD_VECTOR(id, field)                                 \
   castCopy->field.resize(castOriginal->field.size());                          \
-  for (auto i = int64_t(castOriginal->field.size()) - 1; i >= 0; i--) {        \
+  for (auto i = static_cast<int64_t>(castOriginal->field.size()) - 1; i >= 0; i--) {        \
     tasks.push_back({castOriginal->field[i], &castCopy->field[i]});            \
   }
 
diff --git a/src/ir/LocalGraph.cpp b/src/ir/LocalGraph.cpp
index 3c764ef..7cbc0f9 100644
--- a/src/ir/LocalGraph.cpp
+++ b/src/ir/LocalGraph.cpp
@@ -204,7 +204,7 @@
       auto& actions = block.actions;
 
       // move towards the front, handling things as we go
-      for (int i = int(actions.size()) - 1; i >= 0; i--) {
+      for (int i = static_cast<int>(actions.size()) - 1; i >= 0; i--) {
         auto* action = actions[i];
         if (auto* get = action->dynCast<LocalGet>()) {
           allGets[get->index].push_back(get);
diff --git a/src/ir/LocalStructuralDominance.cpp b/src/ir/LocalStructuralDominance.cpp
index 37cd7f4..4dea344 100644
--- a/src/ir/LocalStructuralDominance.cpp
+++ b/src/ir/LocalStructuralDominance.cpp
@@ -163,7 +163,7 @@
               self->pushTask(Scanner::doEndScope, currp);
             }
             auto& list = block->list;
-            for (int i = int(list.size()) - 1; i >= 0; i--) {
+            for (int i = static_cast<int>(list.size()) - 1; i >= 0; i--) {
               self->pushTask(Scanner::scan, &list[i]);
             }
             if (block->name.is()) {
@@ -195,7 +195,7 @@
           }
           case Expression::Id::TryId: {
             auto& list = curr->cast<Try>()->catchBodies;
-            for (int i = int(list.size()) - 1; i >= 0; i--) {
+            for (int i = static_cast<int>(list.size()) - 1; i >= 0; i--) {
               self->pushTask(Scanner::doEndScope, currp);
               self->pushTask(Scanner::scan, &list[i]);
               self->pushTask(Scanner::doBeginScope, currp);
diff --git a/src/ir/bits.h b/src/ir/bits.h
index 6add10a..48da623 100644
--- a/src/ir/bits.h
+++ b/src/ir/bits.h
@@ -38,7 +38,7 @@
 // bit, and all zeros from there. returns the number of masked bits, or 0 if
 // this is not such a mask
 inline uint32_t getMaskedBits(uint32_t mask) {
-  if (mask == uint32_t(-1)) {
+  if (mask == static_cast<uint32_t>(-1)) {
     return 32; // all the bits
   }
   if (mask == 0) {
@@ -128,7 +128,7 @@
 
   Builder builder(wasm);
   auto mask = Bits::lowBitMask(field.getByteSize() * 8);
-  return builder.makeBinary(AndInt32, value, builder.makeConst(int32_t(mask)));
+  return builder.makeBinary(AndInt32, value, builder.makeConst(static_cast<int32_t>(mask)));
 }
 
 // getMaxBits() helper that has pessimistic results for the bits used in locals.
diff --git a/src/ir/effects.h b/src/ir/effects.h
index 2ff7091..6ca650e 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -177,8 +177,8 @@
   //
   // Unlike walking just the body, walking the function will also
   // include the effects of any return calls the function makes. For that
-  // reason, it is a bug if a user of this code calls walk(Expression*) and not
-  // walk(Function*) if their intention is to scan an entire function body.
+  // reason, it is a bug if a user of this code calls walkstatic_cast<Expression*>(and) not
+  // walkstatic_cast<Function*>(if) their intention is to scan an entire function body.
   // Putting it another way, a return_call is syntax sugar for a return and a
   // call, where the call executes at the function scope, so there is a
   // meaningful difference between scanning an expression and scanning
@@ -531,7 +531,7 @@
         self->pushTask(doVisitTry, currp);
         self->pushTask(doEndCatch, currp);
         auto& catchBodies = curr->cast<Try>()->catchBodies;
-        for (int i = int(catchBodies.size()) - 1; i >= 0; i--) {
+        for (int i = static_cast<int>(catchBodies.size()) - 1; i >= 0; i--) {
           self->pushTask(scan, &catchBodies[i]);
         }
         self->pushTask(doStartCatch, currp);
diff --git a/src/ir/iteration.h b/src/ir/iteration.h
index 00f2a73..d7d5828 100644
--- a/src/ir/iteration.h
+++ b/src/ir/iteration.h
@@ -86,7 +86,7 @@
   SmallVector<Expression**, 4> children;
 
   AbstractChildIterator(Expression* parent) {
-    auto* self = (Specific*)this;
+    auto* self = static_cast<Specific*>(this);
 
 #define DELEGATE_ID parent->_id
 
diff --git a/src/ir/linear-execution.h b/src/ir/linear-execution.h
index e8b1923..bda6530 100644
--- a/src/ir/linear-execution.h
+++ b/src/ir/linear-execution.h
@@ -102,7 +102,7 @@
           self->pushTask(SubType::doNoteNonLinear, currp);
         }
         auto& list = curr->cast<Block>()->list;
-        for (int i = int(list.size()) - 1; i >= 0; i--) {
+        for (int i = static_cast<int>(list.size()) - 1; i >= 0; i--) {
           self->pushTask(SubType::scan, &list[i]);
         }
         break;
@@ -164,7 +164,7 @@
         self->pushTask(SubType::doVisitTry, currp);
         self->pushTask(SubType::doNoteNonLinear, currp);
         auto& list = curr->cast<Try>()->catchBodies;
-        for (int i = int(list.size()) - 1; i >= 0; i--) {
+        for (int i = static_cast<int>(list.size()) - 1; i >= 0; i--) {
           self->pushTask(SubType::scan, &list[i]);
           self->pushTask(SubType::doNoteNonLinear, currp);
         }
@@ -181,7 +181,7 @@
         self->pushTask(SubType::doVisitThrow, currp);
         self->pushTask(SubType::doNoteNonLinear, currp);
         auto& list = curr->cast<Throw>()->operands;
-        for (int i = int(list.size()) - 1; i >= 0; i--) {
+        for (int i = static_cast<int>(list.size()) - 1; i >= 0; i--) {
           self->pushTask(SubType::scan, &list[i]);
         }
         break;
diff --git a/src/ir/literal-utils.h b/src/ir/literal-utils.h
index 58f8fe8..4209429 100644
--- a/src/ir/literal-utils.h
+++ b/src/ir/literal-utils.h
@@ -37,7 +37,7 @@
   // (https://bugs.chromium.org/p/v8/issues/detail?id=8460)
   Builder builder(wasm);
   if (type == Type::v128) {
-    return builder.makeUnary(SplatVecI32x4, builder.makeConst(int32_t(0)));
+    return builder.makeUnary(SplatVecI32x4, builder.makeConst(static_cast<int32_t>(0)));
   }
   return builder.makeConstantExpression(Literal::makeZeros(type));
 }
diff --git a/src/ir/manipulation.h b/src/ir/manipulation.h
index 1ad2b11..675b407 100644
--- a/src/ir/manipulation.h
+++ b/src/ir/manipulation.h
@@ -27,7 +27,7 @@
   static_assert(sizeof(OutputType) <= sizeof(InputType),
                 "Can only convert to a smaller size Expression node");
   input->~InputType(); // arena-allocaed, so no destructor, but avoid UB.
-  OutputType* output = (OutputType*)(input);
+  OutputType* output = reinterpret_cast<OutputType*>(input);
   new (output) OutputType;
   return output;
 }
@@ -58,7 +58,7 @@
 inline OutputType* convert(InputType* input, MixedArena& allocator) {
   assert(sizeof(OutputType) <= sizeof(InputType));
   input->~InputType(); // arena-allocaed, so no destructor, but avoid UB.
-  OutputType* output = (OutputType*)(input);
+  OutputType* output = reinterpret_cast<OutputType*>(input);
   new (output) OutputType(allocator);
   return output;
 }
diff --git a/src/ir/match.h b/src/ir/match.h
index 3d42eee..b218ff8 100644
--- a/src/ir/match.h
+++ b/src/ir/match.h
@@ -397,7 +397,7 @@
 // match `Literal` of the expected `Type`
 struct BoolLK {
   static bool matchType(Literal lit) {
-    return lit.type == Type::i32 && (uint32_t)lit.geti32() <= 1U;
+    return lit.type == Type::i32 && static_cast<uint32_t>(lit.geti32()) <= 1U;
   }
   static int32_t getVal(Literal lit) { return lit.geti32(); }
 };
@@ -670,7 +670,7 @@
     nullptr, Internal::I64Lit(nullptr, Internal::Exact<int64_t>(nullptr, x)));
 }
 // Disambiguate literal 0, which could otherwise be interpreted as a pointer
-inline decltype(auto) i64(int x) { return i64(int64_t(x)); }
+inline decltype(auto) i64(int x) { return i64(static_cast<int64_t>(x)); }
 inline decltype(auto) i64(int64_t* binder) {
   return Internal::ConstMatcher(
     nullptr, Internal::I64Lit(nullptr, Internal::Any(binder)));
@@ -693,7 +693,7 @@
     nullptr, Internal::F32Lit(nullptr, Internal::Exact<float>(nullptr, x)));
 }
 // Disambiguate literal 0, which could otherwise be interpreted as a pointer
-inline decltype(auto) f32(int x) { return f32(float(x)); }
+inline decltype(auto) f32(int x) { return f32(static_cast<float>(x)); }
 inline decltype(auto) f32(float* binder) {
   return Internal::ConstMatcher(
     nullptr, Internal::F32Lit(nullptr, Internal::Any(binder)));
@@ -716,7 +716,7 @@
     nullptr, Internal::F64Lit(nullptr, Internal::Exact<double>(nullptr, x)));
 }
 // Disambiguate literal 0, which could otherwise be interpreted as a pointer
-inline decltype(auto) f64(int x) { return f64(double(x)); }
+inline decltype(auto) f64(int x) { return f64(static_cast<double>(x)); }
 inline decltype(auto) f64(double* binder) {
   return Internal::ConstMatcher(
     nullptr, Internal::F64Lit(nullptr, Internal::Any(binder)));
@@ -739,7 +739,7 @@
     nullptr, Internal::IntLit(nullptr, Internal::Exact<int64_t>(nullptr, x)));
 }
 // Disambiguate literal 0, which could otherwise be interpreted as a pointer
-inline decltype(auto) ival(int x) { return ival(int64_t(x)); }
+inline decltype(auto) ival(int x) { return ival(static_cast<int64_t>(x)); }
 inline decltype(auto) ival(int64_t* binder) {
   return Internal::ConstMatcher(
     nullptr, Internal::IntLit(nullptr, Internal::Any(binder)));
@@ -770,7 +770,7 @@
     nullptr, Internal::FloatLit(nullptr, Internal::Exact<double>(nullptr, x)));
 }
 // Disambiguate literal 0, which could otherwise be interpreted as a pointer
-inline decltype(auto) fval(int x) { return fval(double(x)); }
+inline decltype(auto) fval(int x) { return fval(static_cast<double>(x)); }
 inline decltype(auto) fval(double* binder) {
   return Internal::ConstMatcher(
     nullptr, Internal::FloatLit(nullptr, Internal::Any(binder)));
diff --git a/src/ir/memory-utils.h b/src/ir/memory-utils.h
index 2929d17..aad10be 100644
--- a/src/ir/memory-utils.h
+++ b/src/ir/memory-utils.h
@@ -142,7 +142,7 @@
     }
     // create the segment and add in all the data
     auto* c = module.allocator.alloc<Const>();
-    c->value = Literal(int32_t(start));
+    c->value = Literal(static_cast<int32_t>(start));
     c->type = Type::i32;
 
     auto combined = Builder::makeDataSegment();
diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp
index adc14e9..4b7d0d6 100644
--- a/src/ir/module-splitting.cpp
+++ b/src/ir/module-splitting.cpp
@@ -374,7 +374,7 @@
   // Add a global to track whether the secondary module has been loaded yet.
   primary.addGlobal(builder.makeGlobal(LOAD_SECONDARY_STATUS,
                                        Type::i32,
-                                       builder.makeConst(int32_t(0)),
+                                       builder.makeConst(static_cast<int32_t>(0)),
                                        Builder::Mutable));
   primary.addExport(builder.makeExport(
     LOAD_SECONDARY_STATUS, LOAD_SECONDARY_STATUS, ExternalKind::Global));
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp
index ea83a7e..c6808b7 100644
--- a/src/ir/module-utils.cpp
+++ b/src/ir/module-utils.cpp
@@ -778,7 +778,7 @@
   // of its users.
   std::vector<double> weights(groups.size());
   for (size_t i = 0; i < groups.size(); ++i) {
-    weights[i] = double(groupCounts[i]) / groups[i].size();
+    weights[i] = static_cast<double>(groupCounts[i]) / groups[i].size();
   }
   auto sorted = TopologicalSort::sort(deps);
   for (auto it = sorted.rbegin(); it != sorted.rend(); ++it) {
diff --git a/src/ir/possible-constant.h b/src/ir/possible-constant.h
index cd169b2..a6f3ee6 100644
--- a/src/ir/possible-constant.h
+++ b/src/ir/possible-constant.h
@@ -110,14 +110,14 @@
         if (isSigned) {
           value = val.extendS8();
         } else {
-          value = val.and_(Literal(uint32_t(0xff)));
+          value = val.and_(Literal(static_cast<uint32_t>(0xff)));
         }
         break;
       case Field::i16:
         if (isSigned) {
           value = val.extendS16();
         } else {
-          value = val.and_(Literal(uint32_t(0xffff)));
+          value = val.and_(Literal(static_cast<uint32_t>(0xffff)));
         }
         break;
       case Field::WaitQueue:
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index 84affdb..e0cdd1d 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -1983,7 +1983,7 @@
 
   // Operands must exist since there is a cast param, so a param exists.
   assert(operands.size() > 0);
-  for (int i = int(operands.size() - 1); i >= 0; i--) {
+  for (int i = static_cast<int>(operands.size() - 1); i >= 0; i--) {
     auto* operand = operands[i];
 
     if (blockIndexes.get(operand) != callBlockIndex) {
@@ -3011,7 +3011,7 @@
     // We must handle packed fields carefully.
     if (contents.isLiteral()) {
       // This is a constant. We can truncate it and use that value.
-      auto mask = Literal(int32_t(Bits::lowBitMask(field->getByteSize() * 8)));
+      auto mask = Literal(static_cast<int32_t>(Bits::lowBitMask(field->getByteSize() * 8)));
       contents = PossibleContents::literal(contents.getLiteral().and_(mask));
     } else {
       // This is not a constant. We can't even handle a global here, as we'd
@@ -3083,7 +3083,7 @@
 
   if (contents.isLiteral()) {
     // This is a constant. We can sign-extend it and use that value.
-    auto shifts = Literal(int32_t(32 - field->getByteSize() * 8));
+    auto shifts = Literal(static_cast<int32_t>(32 - field->getByteSize() * 8));
     auto lit = contents.getLiteral();
     lit = lit.shl(shifts);
     lit = lit.shrS(shifts);
diff --git a/src/ir/possible-contents.h b/src/ir/possible-contents.h
index a5fdb51..8615597 100644
--- a/src/ir/possible-contents.h
+++ b/src/ir/possible-contents.h
@@ -384,7 +384,7 @@
       }
     } else if (isGlobal()) {
       auto info = getGlobal();
-      o << "GlobalInfo $" << info.name << " K: " << int(info.kind)
+      o << "GlobalInfo $" << info.name << " K: " << static_cast<int>(info.kind)
         << " T: " << getType();
     } else if (auto* coneType = std::get_if<ConeType>(&value)) {
       auto t = coneType->type;
@@ -593,28 +593,28 @@
 template<> struct hash<wasm::ExpressionLocation> {
   size_t operator()(const wasm::ExpressionLocation& loc) const {
     return std::hash<std::pair<size_t, wasm::Index>>{}(
-      {size_t(loc.expr), loc.tupleIndex});
+      {reinterpret_cast<size_t>(loc.expr), loc.tupleIndex});
   }
 };
 
 template<> struct hash<wasm::ParamLocation> {
   size_t operator()(const wasm::ParamLocation& loc) const {
     return std::hash<std::pair<size_t, wasm::Index>>{}(
-      {size_t(loc.func), loc.index});
+      {reinterpret_cast<size_t>(loc.func), loc.index});
   }
 };
 
 template<> struct hash<wasm::LocalLocation> {
   size_t operator()(const wasm::LocalLocation& loc) const {
     return std::hash<std::pair<size_t, wasm::Index>>{}(
-      {size_t(loc.func), loc.index});
+      {reinterpret_cast<size_t>(loc.func), loc.index});
   }
 };
 
 template<> struct hash<wasm::ResultLocation> {
   size_t operator()(const wasm::ResultLocation& loc) const {
     return std::hash<std::pair<size_t, wasm::Index>>{}(
-      {size_t(loc.func), loc.index});
+      {reinterpret_cast<size_t>(loc.func), loc.index});
   }
 };
 
diff --git a/src/ir/utils.h b/src/ir/utils.h
index 44c3ef8..65c5d22 100644
--- a/src/ir/utils.h
+++ b/src/ir/utils.h
@@ -179,7 +179,7 @@
 
   // given a stack of nested expressions, update them all from child to parent
   static void updateStack(ExpressionStack& expressionStack) {
-    for (int i = int(expressionStack.size()) - 1; i >= 0; i--) {
+    for (int i = static_cast<int>(expressionStack.size()) - 1; i >= 0; i--) {
       auto* curr = expressionStack[i];
       ReFinalizeNode().visit(curr);
     }
@@ -194,7 +194,7 @@
       builder.makeUnary(ExtendUInt32, low),
       builder.makeBinary(ShlInt64,
                          builder.makeUnary(ExtendUInt32, high),
-                         builder.makeConst(int64_t(32))));
+                         builder.makeConst(static_cast<int64_t>(32))));
   };
 
   static Expression* recreateI64(Builder& builder, Index low, Index high) {
@@ -208,7 +208,7 @@
       WrapInt64,
       builder.makeBinary(ShrUInt64,
                          builder.makeLocalGet(index, Type::i64),
-                         builder.makeConst(int64_t(32))));
+                         builder.makeConst(static_cast<int64_t>(32))));
   }
 
   static Expression* getI64Low(Builder& builder, Index index) {
diff --git a/src/literal.h b/src/literal.h
index 9eb2717..e03c371 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -170,9 +170,9 @@
   bool isUnsignedMax() const {
     switch (type.getBasic()) {
       case Type::i32:
-        return uint32_t(i32) == std::numeric_limits<uint32_t>::max();
+        return static_cast<uint32_t>(i32) == std::numeric_limits<uint32_t>::max();
       case Type::i64:
-        return uint64_t(i64) == std::numeric_limits<uint64_t>::max();
+        return static_cast<uint64_t>(i64) == std::numeric_limits<uint64_t>::max();
       default:
         WASM_UNREACHABLE("unexpected type");
     }
@@ -187,18 +187,18 @@
   static Literal makeFromInt32(int32_t x, Type type) {
     switch (type.getBasic()) {
       case Type::i32:
-        return Literal(int32_t(x));
+        return Literal(static_cast<int32_t>(x));
       case Type::i64:
-        return Literal(int64_t(x));
+        return Literal(static_cast<int64_t>(x));
       case Type::f32:
-        return Literal(float(x));
+        return Literal(static_cast<float>(x));
       case Type::f64:
-        return Literal(double(x));
+        return Literal(static_cast<double>(x));
       case Type::v128:
         return Literal(std::array<Literal, 4>{{Literal(x),
-                                               Literal(int32_t(0)),
-                                               Literal(int32_t(0)),
-                                               Literal(int32_t(0))}});
+                                               Literal(static_cast<int32_t>(0)),
+                                               Literal(static_cast<int32_t>(0)),
+                                               Literal(static_cast<int32_t>(0))}});
       default:
         WASM_UNREACHABLE("unexpected type");
     }
@@ -206,16 +206,16 @@
   static Literal makeFromInt64(int64_t x, Type type) {
     switch (type.getBasic()) {
       case Type::i32:
-        return Literal(int32_t(x));
+        return Literal(static_cast<int32_t>(x));
       case Type::i64:
-        return Literal(int64_t(x));
+        return Literal(static_cast<int64_t>(x));
       case Type::f32:
-        return Literal(float(x));
+        return Literal(static_cast<float>(x));
       case Type::f64:
-        return Literal(double(x));
+        return Literal(static_cast<double>(x));
       case Type::v128:
         return Literal(
-          std::array<Literal, 2>{{Literal(x), Literal(int64_t(0))}});
+          std::array<Literal, 2>{{Literal(x), Literal(static_cast<int64_t>(0))}});
       default:
         WASM_UNREACHABLE("unexpected type");
     }
@@ -305,7 +305,7 @@
   int32_t geti31(bool signed_ = true) const {
     assert(type.getHeapType().isMaybeShared(HeapType::i31));
     // Cast to unsigned for the left shift to avoid undefined behavior.
-    return signed_ ? int32_t((uint32_t(i32) << 1)) >> 1 : (i32 & 0x7fffffff);
+    return signed_ ? static_cast<int32_t>((static_cast<uint32_t>(i32) << 1)) >> 1 : (i32 & 0x7fffffff);
   }
   bool hasExternPayload() const {
     assert(type.getHeapType().isMaybeShared(HeapType::ext));
@@ -313,7 +313,7 @@
   }
   int32_t getExternPayload() const {
     assert(hasExternPayload());
-    return int32_t(uint32_t(i32) >> 1);
+    return static_cast<int32_t>(static_cast<uint32_t>(i32) >> 1);
   }
   int64_t geti64() const {
     assert(type == Type::i64);
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index 54282cf..15fb529 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -2233,7 +2233,7 @@
                           const std::array<uint8_t, 16>& vals) {
     std::array<Literal, 16> lanes;
     for (size_t i = 0; i < 16; ++i) {
-      lanes[i] = Literal(uint32_t(vals[i]));
+      lanes[i] = Literal(static_cast<uint32_t>(vals[i]));
     }
     return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
   }
@@ -2243,7 +2243,7 @@
                           const std::array<uint16_t, 8>& vals) {
     std::array<Literal, 8> lanes;
     for (size_t i = 0; i < 8; ++i) {
-      lanes[i] = Literal(uint32_t(vals[i]));
+      lanes[i] = Literal(static_cast<uint32_t>(vals[i]));
     }
     return withLoc(pos, irBuilder.makeConst(Literal(lanes)));
   }
diff --git a/src/parser/lexer.cpp b/src/parser/lexer.cpp
index 3064b20..b892274 100644
--- a/src/parser/lexer.cpp
+++ b/src/parser/lexer.cpp
@@ -139,9 +139,9 @@
   template<typename T> bool isSigned() {
     static_assert(std::is_integral_v<T> && std::is_signed_v<T>);
     if (sign == Neg) {
-      return uint64_t(std::numeric_limits<T>::min()) <= n || n == 0;
+      return static_cast<uint64_t>(std::numeric_limits<T>::min()) <= n || n == 0;
     }
-    return n <= uint64_t(std::numeric_limits<T>::max());
+    return n <= static_cast<uint64_t>(std::numeric_limits<T>::max());
   }
 };
 
@@ -845,7 +845,7 @@
         }
         auto lexed = *ictx.lexed();
         ctx.take(lexed);
-        ctx.appendEscaped(char(lexed.n));
+        ctx.appendEscaped(static_cast<char>(lexed.n));
       }
     } else {
       // Normal characters
@@ -1110,9 +1110,9 @@
       if (result->n == 0) {
         return -0.0;
       }
-      return double(int64_t(result->n));
+      return static_cast<double>(static_cast<int64_t>(result->n));
     }
-    return double(result->n);
+    return static_cast<double>(result->n);
   }
   return std::nullopt;
 }
@@ -1147,15 +1147,15 @@
       if (result->n == 0) {
         return -0.0f;
       }
-      return float(int64_t(result->n));
+      return static_cast<float>(static_cast<int64_t>(result->n));
     }
-    return float(result->n);
+    return static_cast<float>(result->n);
   }
   return std::nullopt;
 }
 
 TextPos Lexer::position(const char* c) const {
-  assert(size_t(c - buffer.data()) <= buffer.size());
+  assert(static_cast<size_t>(c - buffer.data()) <= buffer.size());
   TextPos pos{1, 0};
   for (const char* p = buffer.data(); p != c; ++p) {
     if (*p == '\n') {
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index b10e851..87c633a 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -817,7 +817,7 @@
     return ctx.in.err("expected initial size");
   }
   std::optional<uint64_t> m = ctx.in.takeU32();
-  return ctx.makeLimits(uint64_t(*n), m);
+  return ctx.makeLimits(static_cast<uint64_t>(*n), m);
 }
 
 // limits64 ::= n:u64 m:u64?
@@ -827,7 +827,7 @@
     return ctx.in.err("expected initial size");
   }
   std::optional<uint64_t> m = ctx.in.takeU64();
-  return ctx.makeLimits(uint64_t(*n), m);
+  return ctx.makeLimits(static_cast<uint64_t>(*n), m);
 }
 
 // mempagesize? ::= ('(' 'pagesize' u64 ')') ?
@@ -848,7 +848,7 @@
     return ctx.in.err("expected end of mempagesize");
   }
 
-  uint8_t pageSizeLog2 = (uint8_t)Bits::ceilLog2(*pageSize);
+  uint8_t pageSizeLog2 = Bits::ceilLog2(*pageSize);
 
   if (pageSizeLog2 != 0 && pageSizeLog2 != Memory::kDefaultPageSizeLog2) {
     return ctx.in.err("memory page size can only be 1 or 64 KiB");
diff --git a/src/passes/AlignmentLowering.cpp b/src/passes/AlignmentLowering.cpp
index 52849eb..9e62eef 100644
--- a/src/passes/AlignmentLowering.cpp
+++ b/src/passes/AlignmentLowering.cpp
@@ -59,7 +59,7 @@
                            builder.makeLocalGet(temp, addressType),
                            Type::i32,
                            curr->memory),
-          builder.makeConst(int32_t(8))));
+          builder.makeConst(static_cast<int32_t>(8))));
       if (curr->signed_) {
         ret = Bits::makeSignExt(ret, 2, *getModule());
       }
@@ -85,7 +85,7 @@
                                builder.makeLocalGet(temp, addressType),
                                Type::i32,
                                curr->memory),
-              builder.makeConst(int32_t(8)))),
+              builder.makeConst(static_cast<int32_t>(8)))),
           builder.makeBinary(
             OrInt32,
             builder.makeBinary(
@@ -97,7 +97,7 @@
                                builder.makeLocalGet(temp, addressType),
                                Type::i32,
                                curr->memory),
-              builder.makeConst(int32_t(16))),
+              builder.makeConst(static_cast<int32_t>(16))),
             builder.makeBinary(
               ShlInt32,
               builder.makeLoad(1,
@@ -107,7 +107,7 @@
                                builder.makeLocalGet(temp, addressType),
                                Type::i32,
                                curr->memory),
-              builder.makeConst(int32_t(24)))));
+              builder.makeConst(static_cast<int32_t>(24)))));
       } else if (curr->align == 2) {
         ret = builder.makeBinary(
           OrInt32,
@@ -127,7 +127,7 @@
                              builder.makeLocalGet(temp, addressType),
                              Type::i32,
                              curr->memory),
-            builder.makeConst(int32_t(16))));
+            builder.makeConst(static_cast<int32_t>(16))));
       } else {
         WASM_UNREACHABLE("invalid alignment");
       }
@@ -167,7 +167,7 @@
         builder.makeLocalGet(tempPtr, addressType),
         builder.makeBinary(ShrUInt32,
                            builder.makeLocalGet(tempValue, Type::i32),
-                           builder.makeConst(int32_t(8))),
+                           builder.makeConst(static_cast<int32_t>(8))),
         Type::i32,
         curr->memory));
     } else if (curr->bytes == 4) {
@@ -187,7 +187,7 @@
           builder.makeLocalGet(tempPtr, addressType),
           builder.makeBinary(ShrUInt32,
                              builder.makeLocalGet(tempValue, Type::i32),
-                             builder.makeConst(int32_t(8))),
+                             builder.makeConst(static_cast<int32_t>(8))),
           Type::i32,
           curr->memory));
         block->list.push_back(builder.makeStore(
@@ -197,7 +197,7 @@
           builder.makeLocalGet(tempPtr, addressType),
           builder.makeBinary(ShrUInt32,
                              builder.makeLocalGet(tempValue, Type::i32),
-                             builder.makeConst(int32_t(16))),
+                             builder.makeConst(static_cast<int32_t>(16))),
           Type::i32,
           curr->memory));
         block->list.push_back(builder.makeStore(
@@ -207,7 +207,7 @@
           builder.makeLocalGet(tempPtr, addressType),
           builder.makeBinary(ShrUInt32,
                              builder.makeLocalGet(tempValue, Type::i32),
-                             builder.makeConst(int32_t(24))),
+                             builder.makeConst(static_cast<int32_t>(24))),
           Type::i32,
           curr->memory));
       } else if (curr->align == 2) {
@@ -226,7 +226,7 @@
           builder.makeLocalGet(tempPtr, addressType),
           builder.makeBinary(ShrUInt32,
                              builder.makeLocalGet(tempValue, Type::i32),
-                             builder.makeConst(int32_t(16))),
+                             builder.makeConst(static_cast<int32_t>(16))),
           Type::i32,
           curr->memory));
       } else {
@@ -301,7 +301,7 @@
                                         curr->memory));
         high = builder.makeUnary(ExtendUInt32, high);
         high =
-          builder.makeBinary(ShlInt64, high, builder.makeConst(int64_t(32)));
+          builder.makeBinary(ShlInt64, high, builder.makeConst(static_cast<int64_t>(32)));
         auto* combined = builder.makeBinary(OrInt64, low, high);
         replacement = builder.makeSequence(set, combined);
         // Ensure the proper output type.
@@ -375,7 +375,7 @@
         Expression* high =
           builder.makeBinary(ShrUInt64,
                              builder.makeLocalGet(tempValue, Type::i64),
-                             builder.makeConst(int64_t(32)));
+                             builder.makeConst(static_cast<int64_t>(32)));
         high = builder.makeUnary(WrapInt64, high);
         // Note that the alignment is assumed to be the same here, even though
         // we add an offset of 4. That is because this is an unaligned store, so
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index 48f9cc5..56e4230 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -888,7 +888,7 @@
   Expression* makeGetStackPos() {
     return makeLoad(pointerType.getByteSize(),
                     false,
-                    int(DataOffset::BStackPos),
+                    static_cast<int>(DataOffset::BStackPos),
                     pointerType.getByteSize(),
                     makeGlobalGet(ASYNCIFY_DATA, pointerType),
                     pointerType,
@@ -901,7 +901,7 @@
     }
     auto literal = Literal::makeFromInt64(by, pointerType);
     return makeStore(pointerType.getByteSize(),
-                     int(DataOffset::BStackPos),
+                     static_cast<int>(DataOffset::BStackPos),
                      pointerType.getByteSize(),
                      makeGlobalGet(ASYNCIFY_DATA, pointerType),
                      makeBinary(Abstract::getBinary(pointerType, Abstract::Add),
@@ -914,7 +914,7 @@
   Expression* makeStateCheck(State value) {
     return makeBinary(EqInt32,
                       makeGlobalGet(ASYNCIFY_STATE, Type::i32),
-                      makeConst(Literal(int32_t(value))));
+                      makeConst(Literal(static_cast<int32_t>(value))));
   }
 };
 
@@ -1238,7 +1238,7 @@
     return builder->makeIf(
       builder->makeStateCheck(State::Unwinding),
       builder->makeCall(
-        ASYNCIFY_UNWIND, {builder->makeConst(int32_t(index))}, Type::none),
+        ASYNCIFY_UNWIND, {builder->makeConst(static_cast<int32_t>(index))}, Type::none),
       ifNotUnwinding);
   }
 
@@ -1246,7 +1246,7 @@
     // Emit an intrinsic for this, as we store the index into a local, and
     // don't want it to be seen by asyncify itself.
     return builder->makeCall(ASYNCIFY_CHECK_CALL_INDEX,
-                             {builder->makeConst(int32_t(index))},
+                             {builder->makeConst(static_cast<int32_t>(index))},
                              Type::i32);
   }
 
@@ -1367,7 +1367,7 @@
     auto check = builder->makeIf(
       builder->makeBinary(NeInt32,
                           builder->makeGlobalGet(ASYNCIFY_STATE, Type::i32),
-                          builder->makeConst(int32_t(State::Normal))),
+                          builder->makeConst(static_cast<int32_t>(State::Normal))),
       builder->makeUnreachable());
     if (call->type.isConcrete()) {
       auto temp = builder->addVar(function, call->type);
@@ -1930,7 +1930,7 @@
 
     auto asyncifyState = builder.makeGlobal(ASYNCIFY_STATE,
                                             Type::i32,
-                                            builder.makeConst(int32_t(0)),
+                                            builder.makeConst(static_cast<int32_t>(0)),
                                             Builder::Mutable);
     if (imported) {
       asyncifyState->module = ENV;
@@ -1965,7 +1965,7 @@
       }
       auto* body = builder.makeBlock();
       body->list.push_back(builder.makeGlobalSet(
-        ASYNCIFY_STATE, builder.makeConst(int32_t(state))));
+        ASYNCIFY_STATE, builder.makeConst(static_cast<int32_t>(state))));
       if (setData) {
         body->list.push_back(builder.makeGlobalSet(
           ASYNCIFY_DATA, builder.makeLocalGet(0, pointerType)));
@@ -1974,7 +1974,7 @@
       auto* stackPos =
         builder.makeLoad(pointerType.getByteSize(),
                          false,
-                         int(DataOffset::BStackPos),
+                         static_cast<int>(DataOffset::BStackPos),
                          pointerType.getByteSize(),
                          builder.makeGlobalGet(ASYNCIFY_DATA, pointerType),
                          pointerType,
@@ -1982,7 +1982,7 @@
       auto* stackEnd =
         builder.makeLoad(pointerType.getByteSize(),
                          false,
-                         int(pointerType == Type::i64 ? DataOffset::BStackEnd64
+                         static_cast<int>(pointerType == Type::i64 ? DataOffset::BStackEnd64
                                                       : DataOffset::BStackEnd),
                          pointerType.getByteSize(),
                          builder.makeGlobalGet(ASYNCIFY_DATA, pointerType),
diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp
index 93c3d8d..3ce93b5 100644
--- a/src/passes/CoalesceLocals.cpp
+++ b/src/passes/CoalesceLocals.cpp
@@ -186,7 +186,7 @@
     auto& actions = curr->contents.actions;
     std::vector<bool> endsLiveRange(actions.size(), false);
     auto live = curr->contents.end;
-    for (int i = int(actions.size()) - 1; i >= 0; i--) {
+    for (int i = static_cast<int>(actions.size()) - 1; i >= 0; i--) {
       auto& action = actions[i];
       auto index = action.index;
       if (action.isGet()) {
@@ -371,7 +371,7 @@
       std::cerr << "  ";
     }
     for (Index j = i + 1; j < numLocals; j++) {
-      std::cerr << int(interferes(i, j)) << ' ';
+      std::cerr << static_cast<int>(interferes(i, j)) << ' ';
     }
     std::cerr << " : $" << i << '\n';
   }
@@ -381,7 +381,7 @@
       std::cerr << "  ";
     }
     for (Index j = i + 1; j < numLocals; j++) {
-      std::cerr << int(getCopies(i, j)) << ' ';
+      std::cerr << static_cast<int>(getCopies(i, j)) << ' ';
     }
     std::cerr << " : $" << i << '\n';
   }
diff --git a/src/passes/DeNaN.cpp b/src/passes/DeNaN.cpp
index 0251a0c..4a75ba1 100644
--- a/src/passes/DeNaN.cpp
+++ b/src/passes/DeNaN.cpp
@@ -57,13 +57,13 @@
     auto* c = expr->dynCast<Const>();
     if (expr->type == Type::f32) {
       if (c && c->value.isNaN()) {
-        replacement = builder.makeConst(float(0));
+        replacement = builder.makeConst(static_cast<float>(0));
       } else if (!c) {
         replacement = builder.makeCall(deNan32, {expr}, Type::f32);
       }
     } else if (expr->type == Type::f64) {
       if (c && c->value.isNaN()) {
-        replacement = builder.makeConst(double(0));
+        replacement = builder.makeConst(static_cast<double>(0));
       } else if (!c) {
         replacement = builder.makeCall(deNan64, {expr}, Type::f64);
       }
@@ -133,8 +133,8 @@
       module);
 
     // Add helper functions after the walk, so they are not instrumented.
-    addFunc(module, deNan32, Type::f32, Literal(float(0)), EqFloat32);
-    addFunc(module, deNan64, Type::f64, Literal(double(0)), EqFloat64);
+    addFunc(module, deNan32, Type::f32, Literal(static_cast<float>(0)), EqFloat32);
+    addFunc(module, deNan64, Type::f64, Literal(static_cast<double>(0)), EqFloat64);
 
     if (module->features.hasSIMD()) {
       uint8_t zero128[16] = {};
diff --git a/src/passes/GUFA.cpp b/src/passes/GUFA.cpp
index a4567aa..7c05283 100644
--- a/src/passes/GUFA.cpp
+++ b/src/passes/GUFA.cpp
@@ -236,7 +236,7 @@
       // no value is possible there, and the intersection is empty, so we will
       // get here and emit a 0. That 0 will never be reached as the None child
       // will be turned into an unreachable, so it does not cause any problem.
-      auto* result = Builder(*getModule()).makeConst(Literal(int32_t(0)));
+      auto* result = Builder(*getModule()).makeConst(Literal(static_cast<int32_t>(0)));
       replaceCurrent(getDroppedChildrenAndAppend(
         curr, *getModule(), getPassOptions(), result));
     }
@@ -257,7 +257,7 @@
       auto intendedContents = PossibleContents::coneType(curr->castType);
 
       auto optimize = [&](int32_t result) {
-        auto* last = Builder(*getModule()).makeConst(Literal(int32_t(result)));
+        auto* last = Builder(*getModule()).makeConst(Literal(static_cast<int32_t>(result)));
         replaceCurrent(getDroppedChildrenAndAppend(
           curr, *getModule(), getPassOptions(), last));
       };
diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp
index 7224f25..9102648 100644
--- a/src/passes/Heap2Local.cpp
+++ b/src/passes/Heap2Local.cpp
@@ -810,7 +810,7 @@
     // The result must be 0, since the allocation is not null. Drop the RefIs
     // and append that.
     replaceCurrent(builder.makeSequence(
-      builder.makeDrop(curr), builder.makeConst(Literal(int32_t(0)))));
+      builder.makeDrop(curr), builder.makeConst(Literal(static_cast<int32_t>(0)))));
   }
 
   void visitRefEq(RefEq* curr) {
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index d127ebd..dfc586b 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -120,7 +120,7 @@
       curr->type = Type::i32;
       auto high = builder->makeGlobal(makeHighName(curr->name),
                                       Type::i32,
-                                      builder->makeConst(int32_t(0)),
+                                      builder->makeConst(static_cast<int32_t>(0)),
                                       curr->mutable_ ? Builder::Mutable
                                                      : Builder::Immutable);
       if (curr->imported()) {
@@ -128,9 +128,9 @@
       } else {
         if (auto* c = curr->init->dynCast<Const>()) {
           uint64_t value = c->value.geti64();
-          c->value = Literal(uint32_t(value));
+          c->value = Literal(static_cast<uint32_t>(value));
           c->type = Type::i32;
-          high->init = builder->makeConst(uint32_t(value >> 32));
+          high->init = builder->makeConst(static_cast<uint32_t>(value >> 32));
         } else if (auto* get = curr->init->dynCast<GlobalGet>()) {
           high->init =
             builder->makeGlobalGet(makeHighName(get->name), Type::i32);
@@ -147,7 +147,7 @@
     auto* highBits = new Global();
     highBits->type = Type::i32;
     highBits->name = INT64_TO_32_HIGH_BITS;
-    highBits->init = builder->makeConst(int32_t(0));
+    highBits->init = builder->makeConst(static_cast<int32_t>(0));
     highBits->mutable_ = true;
     module->addGlobal(highBits);
     PostWalker<I64ToI32Lowering>::doWalkModule(module);
@@ -426,7 +426,7 @@
         builder->makeLoad(4,
                           curr->signed_,
                           curr->offset + 4,
-                          std::min(uint32_t(curr->align), uint32_t(4)),
+                          std::min(static_cast<uint32_t>(curr->align), static_cast<uint32_t>(4)),
                           builder->makeLocalGet(ptrTemp, Type::i32),
                           Type::i32,
                           curr->memory));
@@ -435,14 +435,14 @@
         highBits,
         builder->makeBinary(ShrSInt32,
                             builder->makeLocalGet(lowBits, Type::i32),
-                            builder->makeConst(int32_t(31))));
+                            builder->makeConst(static_cast<int32_t>(31))));
     } else {
       loadHigh =
-        builder->makeLocalSet(highBits, builder->makeConst(int32_t(0)));
+        builder->makeLocalSet(highBits, builder->makeConst(static_cast<int32_t>(0)));
     }
     curr->type = Type::i32;
-    curr->bytes = std::min(curr->bytes, uint8_t(4));
-    curr->align = std::min(uint32_t(curr->align), uint32_t(4));
+    curr->bytes = std::min(curr->bytes, static_cast<uint8_t>(4));
+    curr->align = std::min(static_cast<uint32_t>(curr->align), static_cast<uint32_t>(4));
     curr->ptr = builder->makeLocalGet(ptrTemp, Type::i32);
     Block* result =
       builder->blockify(setPtr,
@@ -461,8 +461,8 @@
     assert(!curr->isAtomic() && "atomic store not implemented");
     TempVar highBits = fetchOutParam(curr->value);
     uint8_t bytes = curr->bytes;
-    curr->bytes = std::min(curr->bytes, uint8_t(4));
-    curr->align = std::min(uint32_t(curr->align), uint32_t(4));
+    curr->bytes = std::min(curr->bytes, static_cast<uint8_t>(4));
+    curr->align = std::min(static_cast<uint32_t>(curr->align), static_cast<uint32_t>(4));
     curr->valueType = Type::i32;
     if (bytes == 8) {
       TempVar ptrTemp = getTemp();
@@ -472,7 +472,7 @@
       Store* storeHigh =
         builder->makeStore(4,
                            curr->offset + 4,
-                           std::min(uint32_t(curr->align), uint32_t(4)),
+                           std::min(static_cast<uint32_t>(curr->align), static_cast<uint32_t>(4)),
                            builder->makeLocalGet(ptrTemp, Type::i32),
                            builder->makeLocalGet(highBits, Type::i32),
                            Type::i32,
@@ -494,9 +494,9 @@
     TempVar highBits = getTemp();
     auto* getLow = builder->makeCall(
       ABI::wasm2js::ATOMIC_RMW_I64,
-      {builder->makeConst(int32_t(curr->op)),
-       builder->makeConst(int32_t(curr->bytes)),
-       builder->makeConst(int32_t(curr->offset)),
+      {builder->makeConst(static_cast<int32_t>(curr->op)),
+       builder->makeConst(static_cast<int32_t>(curr->bytes)),
+       builder->makeConst(static_cast<int32_t>(curr->offset)),
        curr->ptr,
        curr->value,
        builder->makeLocalGet(fetchOutParam(curr->value), Type::i32)},
@@ -519,7 +519,7 @@
     // The last parameter is an i64, so we cannot leave it as it is
     replaceCurrent(builder->makeCall(
       ABI::wasm2js::ATOMIC_WAIT_I32,
-      {builder->makeConst(int32_t(curr->offset)),
+      {builder->makeConst(static_cast<int32_t>(curr->offset)),
        curr->ptr,
        curr->expected,
        curr->timeout,
@@ -536,10 +536,10 @@
     }
     TempVar highBits = getTemp();
     Const* lowVal =
-      builder->makeConst(int32_t(curr->value.geti64() & 0xffffffff));
+      builder->makeConst(static_cast<int32_t>(curr->value.geti64() & 0xffffffff));
     LocalSet* setHigh = builder->makeLocalSet(
       highBits,
-      builder->makeConst(int32_t(uint64_t(curr->value.geti64()) >> 32)));
+      builder->makeConst(static_cast<int32_t>(static_cast<uint64_t>(curr->value.geti64()) >> 32)));
     Block* result = builder->blockify(setHigh, lowVal);
     setOutParam(result, std::move(highBits));
     replaceCurrent(result);
@@ -559,7 +559,7 @@
   void lowerExtendUInt32(Unary* curr) {
     TempVar highBits = getTemp();
     Block* result = builder->blockify(
-      builder->makeLocalSet(highBits, builder->makeConst(int32_t(0))),
+      builder->makeLocalSet(highBits, builder->makeConst(static_cast<int32_t>(0))),
       curr->value);
     setOutParam(result, std::move(highBits));
     replaceCurrent(result);
@@ -574,7 +574,7 @@
       highBits,
       builder->makeBinary(ShrSInt32,
                           builder->makeLocalGet(lowBits, Type::i32),
-                          builder->makeConst(int32_t(31))));
+                          builder->makeConst(static_cast<int32_t>(31))));
 
     Block* result = builder->blockify(
       setLow, setHigh, builder->makeLocalGet(lowBits, Type::i32));
@@ -607,7 +607,7 @@
       highBits,
       builder->makeBinary(ShrSInt32,
                           builder->makeLocalGet(lowBits, Type::i32),
-                          builder->makeConst(int32_t(31))));
+                          builder->makeConst(static_cast<int32_t>(31))));
 
     Block* result = builder->blockify(
       setLow, setHigh, builder->makeLocalGet(lowBits, Type::i32));
@@ -631,10 +631,10 @@
         ABI::wasm2js::SCRATCH_STORE_F64, {curr->value}, Type::none),
       builder->makeLocalSet(highBits,
                             builder->makeCall(ABI::wasm2js::SCRATCH_LOAD_I32,
-                                              {builder->makeConst(int32_t(1))},
+                                              {builder->makeConst(static_cast<int32_t>(1))},
                                               Type::i32)),
       builder->makeCall(ABI::wasm2js::SCRATCH_LOAD_I32,
-                        {builder->makeConst(int32_t(0))},
+                        {builder->makeConst(static_cast<int32_t>(0))},
                         Type::i32));
     setOutParam(result, std::move(highBits));
     replaceCurrent(result);
@@ -648,10 +648,10 @@
     TempVar highBits = fetchOutParam(curr->value);
     Block* result = builder->blockify(
       builder->makeCall(ABI::wasm2js::SCRATCH_STORE_I32,
-                        {builder->makeConst(int32_t(0)), curr->value},
+                        {builder->makeConst(static_cast<int32_t>(0)), curr->value},
                         Type::none),
       builder->makeCall(ABI::wasm2js::SCRATCH_STORE_I32,
-                        {builder->makeConst(int32_t(1)),
+                        {builder->makeConst(static_cast<int32_t>(1)),
                          builder->makeLocalGet(highBits, Type::i32)},
                         Type::none),
       builder->makeCall(ABI::wasm2js::SCRATCH_LOAD_F64, {}, Type::f64));
@@ -663,18 +663,18 @@
   void lowerTruncFloatToInt(Unary* curr) {
     // hiBits = if abs(f) >= 1.0 {
     //    if f > 0.0 {
-    //        (unsigned) min(
-    //          floor(f / (float) U32_MAX),
-    //          (float) U32_MAX - 1,
+    //        static_cast<unsigned>(min)(
+    //          floor(f / static_cast<float>(U32_MAX)),
+    //          static_cast<float>(U32_MAX) - 1,
     //        )
     //    } else {
-    //        (unsigned) ceil((f - (float) (unsigned) f) / ((float) U32_MAX))
+    //        static_cast<unsigned>(ceil)((f - static_cast<float>static_cast<unsigned>(f)) / (static_cast<float>(U32_MAX)))
     //    }
     // } else {
     //    0
     // }
     //
-    // loBits = (unsigned) f;
+    // loBits = static_cast<unsigned>(f);
 
     Literal litZero, litOne, u32Max;
     UnaryOp trunc, convert, abs, floor, ceil;
@@ -683,9 +683,9 @@
     switch (curr->op) {
       case TruncSFloat32ToInt64:
       case TruncUFloat32ToInt64: {
-        litZero = Literal((float)0);
-        litOne = Literal((float)1);
-        u32Max = Literal(((float)UINT_MAX) + 1);
+        litZero = Literal(static_cast<float>(0));
+        litOne = Literal(static_cast<float>(1));
+        u32Max = Literal((static_cast<float>(UINT_MAX)) + 1);
         trunc = TruncUFloat32ToInt32;
         convert = ConvertUInt32ToFloat32;
         localType = Type::f32;
@@ -701,9 +701,9 @@
       }
       case TruncSFloat64ToInt64:
       case TruncUFloat64ToInt64: {
-        litZero = Literal((double)0);
-        litOne = Literal((double)1);
-        u32Max = Literal(((double)UINT_MAX) + 1);
+        litZero = Literal(static_cast<double>(0));
+        litOne = Literal(static_cast<double>(1));
+        u32Max = Literal((static_cast<double>(UINT_MAX)) + 1);
         trunc = TruncUFloat64ToInt32;
         convert = ConvertUInt32ToFloat64;
         localType = Type::f64;
@@ -756,7 +756,7 @@
         builder->makeUnary(abs, builder->makeLocalGet(f, localType)),
         builder->makeConst(litOne)),
       highBitsCalc,
-      builder->makeConst(int32_t(0)));
+      builder->makeConst(static_cast<int32_t>(0)));
     Block* result = builder->blockify(
       builder->makeLocalSet(f, curr->value),
       builder->makeLocalSet(highBits, highBitsVal),
@@ -772,8 +772,8 @@
     //
     // For example for i64 -> f32 we generate:
     //
-    //  ((double) (unsigned) lowBits) +
-    //      ((double) U32_MAX) * ((double) (int) highBits)
+    //  (static_cast<double>static_cast<unsigned>(lowBits)) +
+    //      (static_cast<double>(U32_MAX)) * (static_cast<double>(static_cast)<int>(highBits))
     //
     // Mostly just shuffling things around here with coercions and whatnot!
     // Note though that all arithmetic is done with f64 to have as much
@@ -830,14 +830,14 @@
 
     Expression* result = builder->blockify(
       builder->makeLocalSet(lowBits, curr->value),
-      builder->makeLocalSet(highResult, builder->makeConst(int32_t(0))),
+      builder->makeLocalSet(highResult, builder->makeConst(static_cast<int32_t>(0))),
       builder->makeBinary(
         AddFloat64,
         builder->makeUnary(ConvertUInt32ToFloat64,
                            builder->makeLocalGet(lowBits, Type::i32)),
         builder->makeBinary(
           MulFloat64,
-          builder->makeConst((double)UINT_MAX + 1),
+          builder->makeConst(static_cast<double>(UINT_MAX) + 1),
           builder->makeUnary(convertHigh,
                              builder->makeLocalGet(highBits, Type::i32)))));
 
@@ -868,18 +868,18 @@
       Binary* check =
         builder->makeBinary(EqInt32,
                             builder->makeLocalGet(firstResult, Type::i32),
-                            builder->makeConst(int32_t(32)));
+                            builder->makeConst(static_cast<int32_t>(32)));
 
       If* conditional = builder->makeIf(
         check,
         builder->makeBinary(
           AddInt32,
           builder->makeUnary(op32, builder->makeLocalGet(second, Type::i32)),
-          builder->makeConst(int32_t(32))),
+          builder->makeConst(static_cast<int32_t>(32))),
         builder->makeLocalGet(firstResult, Type::i32));
 
       LocalSet* setHigh =
-        builder->makeLocalSet(highResult, builder->makeConst(int32_t(0)));
+        builder->makeLocalSet(highResult, builder->makeConst(static_cast<int32_t>(0)));
 
       setOutParam(result, std::move(highResult));
 
@@ -1009,7 +1009,7 @@
       highResult,
       builder->makeBinary(AddInt32,
                           builder->makeLocalGet(highResult, Type::i32),
-                          builder->makeConst(int32_t(1))));
+                          builder->makeConst(static_cast<int32_t>(1))));
     If* checkOverflow = builder->makeIf(
       builder->makeBinary(LtUInt32,
                           builder->makeLocalGet(lowResult, Type::i32),
@@ -1097,7 +1097,7 @@
         builder->makeBinary(ShlInt32,
                             builder->makeLocalGet(leftLow, Type::i32),
                             builder->makeLocalGet(shift, Type::i32))),
-      builder->makeConst(int32_t(0)));
+      builder->makeConst(static_cast<int32_t>(0)));
   }
 
   // a >> b where `b` >= 32
@@ -1112,7 +1112,7 @@
         highBits,
         builder->makeBinary(ShrSInt32,
                             builder->makeLocalGet(leftHigh, Type::i32),
-                            builder->makeConst(int32_t(31)))),
+                            builder->makeConst(static_cast<int32_t>(31)))),
       builder->makeBinary(ShrSInt32,
                           builder->makeLocalGet(leftHigh, Type::i32),
                           builder->makeLocalGet(shift, Type::i32)));
@@ -1120,7 +1120,7 @@
 
   Block* makeLargeShrU(Index highBits, Index leftHigh, Index shift) {
     return builder->blockify(
-      builder->makeLocalSet(highBits, builder->makeConst(int32_t(0))),
+      builder->makeLocalSet(highBits, builder->makeConst(static_cast<int32_t>(0))),
       builder->makeBinary(ShrUInt32,
                           builder->makeLocalGet(leftHigh, Type::i32),
                           builder->makeLocalGet(shift, Type::i32)));
@@ -1222,13 +1222,13 @@
       shift,
       builder->makeBinary(AndInt32,
                           builder->makeLocalGet(rightLow, Type::i32),
-                          builder->makeConst(int32_t(32 - 1))));
+                          builder->makeConst(static_cast<int32_t>(32 - 1))));
     Binary* isLargeShift = builder->makeBinary(
       LeUInt32,
-      builder->makeConst(int32_t(32)),
+      builder->makeConst(static_cast<int32_t>(32)),
       builder->makeBinary(AndInt32,
                           builder->makeLocalGet(rightLow, Type::i32),
-                          builder->makeConst(int32_t(64 - 1))));
+                          builder->makeConst(static_cast<int32_t>(64 - 1))));
     Block* largeShiftBlock;
     switch (op) {
       case ShlInt64:
@@ -1246,12 +1246,12 @@
     Binary* shiftMask = builder->makeBinary(
       SubInt32,
       builder->makeBinary(ShlInt32,
-                          builder->makeConst(int32_t(1)),
+                          builder->makeConst(static_cast<int32_t>(1)),
                           builder->makeLocalGet(shift, Type::i32)),
-      builder->makeConst(int32_t(1)));
+      builder->makeConst(static_cast<int32_t>(1)));
     Binary* widthLessShift =
       builder->makeBinary(SubInt32,
-                          builder->makeConst(int32_t(32)),
+                          builder->makeConst(static_cast<int32_t>(32)),
                           builder->makeLocalGet(shift, Type::i32));
     Block* smallShiftBlock;
     switch (op) {
@@ -1403,11 +1403,11 @@
                           builder->makeLocalGet(leftLow, Type::i32),
                           builder->makeLocalGet(rightLow, Type::i32));
     If* lowIf = builder->makeIf(
-      compLow, builder->makeConst(int32_t(0)), builder->makeConst(int32_t(1)));
+      compLow, builder->makeConst(static_cast<int32_t>(0)), builder->makeConst(static_cast<int32_t>(1)));
     If* highIf2 =
-      builder->makeIf(compHigh2, lowIf, builder->makeConst(int32_t(0)));
+      builder->makeIf(compHigh2, lowIf, builder->makeConst(static_cast<int32_t>(0)));
     If* highIf1 =
-      builder->makeIf(compHigh1, builder->makeConst(int32_t(1)), highIf2);
+      builder->makeIf(compHigh1, builder->makeConst(static_cast<int32_t>(1)), highIf2);
     return builder->blockify(result, highIf1);
   }
 
diff --git a/src/passes/InstrumentBranchHints.cpp b/src/passes/InstrumentBranchHints.cpp
index ac87b8f..9a4e1e4 100644
--- a/src/passes/InstrumentBranchHints.cpp
+++ b/src/passes/InstrumentBranchHints.cpp
@@ -168,8 +168,8 @@
     // Instrument the condition.
     auto tempLocal = builder.addVar(getFunction(), Type::i32);
     auto* set = builder.makeLocalSet(tempLocal, curr->condition);
-    auto* idConst = builder.makeConst(Literal(int32_t(id)));
-    auto* guess = builder.makeConst(Literal(int32_t(*likely)));
+    auto* idConst = builder.makeConst(Literal(static_cast<int32_t>(id)));
+    auto* guess = builder.makeConst(Literal(static_cast<int32_t>(*likely)));
     auto* get1 = builder.makeLocalGet(tempLocal, Type::i32);
     auto* log = builder.makeCall(logBranch, {idConst, guess, get1}, Type::none);
     auto* get2 = builder.makeLocalGet(tempLocal, Type::i32);
diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp
index 267e806..43c9ba4 100644
--- a/src/passes/InstrumentLocals.cpp
+++ b/src/passes/InstrumentLocals.cpp
@@ -106,8 +106,8 @@
       }
     }
     replaceCurrent(builder.makeCall(import,
-                                    {builder.makeConst(int32_t(id++)),
-                                     builder.makeConst(int32_t(curr->index)),
+                                    {builder.makeConst(static_cast<int32_t>(id++)),
+                                     builder.makeConst(static_cast<int32_t>(curr->index)),
                                      curr},
                                     curr->type));
   }
@@ -160,8 +160,8 @@
       }
     }
     curr->value = builder.makeCall(import,
-                                   {builder.makeConst(int32_t(id++)),
-                                    builder.makeConst(int32_t(curr->index)),
+                                   {builder.makeConst(static_cast<int32_t>(id++)),
+                                    builder.makeConst(static_cast<int32_t>(curr->index)),
                                     curr->value},
                                    curr->value->type);
   }
diff --git a/src/passes/InstrumentMemory.cpp b/src/passes/InstrumentMemory.cpp
index ddbac6a..483b2de 100644
--- a/src/passes/InstrumentMemory.cpp
+++ b/src/passes/InstrumentMemory.cpp
@@ -120,8 +120,8 @@
     auto addressType = mem->addressType;
     auto offset = builder.makeConstPtr(curr->offset.addr, addressType);
     curr->ptr = builder.makeCall(load_ptr,
-                                 {builder.makeConst(int32_t(id)),
-                                  builder.makeConst(int32_t(curr->bytes)),
+                                 {builder.makeConst(static_cast<int32_t>(id)),
+                                  builder.makeConst(static_cast<int32_t>(curr->bytes)),
                                   offset,
                                   curr->ptr},
                                  addressType);
@@ -143,7 +143,7 @@
         return; // TODO: other types, unreachable, etc.
     }
     replaceCurrent(builder.makeCall(
-      target, {builder.makeConst(int32_t(id)), curr}, curr->type));
+      target, {builder.makeConst(static_cast<int32_t>(id)), curr}, curr->type));
   }
 
   void visitStore(Store* curr) {
@@ -155,8 +155,8 @@
     auto addressType = mem->addressType;
     auto offset = builder.makeConstPtr(curr->offset.addr, addressType);
     curr->ptr = builder.makeCall(store_ptr,
-                                 {builder.makeConst(int32_t(id)),
-                                  builder.makeConst(int32_t(curr->bytes)),
+                                 {builder.makeConst(static_cast<int32_t>(id)),
+                                  builder.makeConst(static_cast<int32_t>(curr->bytes)),
                                   offset,
                                   curr->ptr},
                                  addressType);
@@ -178,7 +178,7 @@
         return; // TODO: other types, unreachable, etc.
     }
     curr->value = builder.makeCall(
-      target, {builder.makeConst(int32_t(id)), curr->value}, curr->value->type);
+      target, {builder.makeConst(static_cast<int32_t>(id)), curr->value}, curr->value->type);
   }
 
   void visitStructGet(StructGet* curr) {
@@ -198,7 +198,7 @@
       return; // TODO: other types, unreachable, etc.
     }
     replaceCurrent(builder.makeCall(
-      target, {builder.makeConst(int32_t(id++)), curr}, curr->type));
+      target, {builder.makeConst(static_cast<int32_t>(id++)), curr}, curr->type));
   }
 
   void visitStructSet(StructSet* curr) {
@@ -219,7 +219,7 @@
     }
     curr->value =
       builder.makeCall(target,
-                       {builder.makeConst(int32_t(id++)), curr->value},
+                       {builder.makeConst(static_cast<int32_t>(id++)), curr->value},
                        curr->value->type);
   }
 
@@ -229,7 +229,7 @@
     Builder builder(*getModule());
     curr->index =
       builder.makeCall(array_get_index,
-                       {builder.makeConst(int32_t(id++)), curr->index},
+                       {builder.makeConst(static_cast<int32_t>(id++)), curr->index},
                        Type::i32);
     Name target;
     if (curr->type == Type::i32) {
@@ -244,7 +244,7 @@
       return; // TODO: other types, unreachable, etc.
     }
     replaceCurrent(builder.makeCall(
-      target, {builder.makeConst(int32_t(id++)), curr}, curr->type));
+      target, {builder.makeConst(static_cast<int32_t>(id++)), curr}, curr->type));
   }
 
   void visitArraySet(ArraySet* curr) {
@@ -253,7 +253,7 @@
     Builder builder(*getModule());
     curr->index =
       builder.makeCall(array_set_index,
-                       {builder.makeConst(int32_t(id++)), curr->index},
+                       {builder.makeConst(static_cast<int32_t>(id++)), curr->index},
                        Type::i32);
     Name target;
     if (curr->value->type == Type::i32) {
@@ -269,7 +269,7 @@
     }
     curr->value =
       builder.makeCall(target,
-                       {builder.makeConst(int32_t(id++)), curr->value},
+                       {builder.makeConst(static_cast<int32_t>(id++)), curr->value},
                        curr->value->type);
   }
 
@@ -281,10 +281,10 @@
     auto addressType = getModule()->getMemory(curr->memory)->addressType;
     curr->delta =
       builder.makeCall(memory_grow_pre,
-                       {builder.makeConst(int32_t(id)), curr->delta},
+                       {builder.makeConst(static_cast<int32_t>(id)), curr->delta},
                        addressType);
     replaceCurrent(builder.makeCall(
-      memory_grow_post, {builder.makeConst(int32_t(id)), curr}, addressType));
+      memory_grow_post, {builder.makeConst(static_cast<int32_t>(id)), curr}, addressType));
   }
 
   void visitModule(Module* curr) {
diff --git a/src/passes/LogExecution.cpp b/src/passes/LogExecution.cpp
index c194fdc..ff12dbf 100644
--- a/src/passes/LogExecution.cpp
+++ b/src/passes/LogExecution.cpp
@@ -108,7 +108,7 @@
     static Index id = 0;
     Builder builder(*getModule());
     return builder.makeSequence(
-      builder.makeCall(LOGGER, {builder.makeConst(int32_t(id++))}, Type::none),
+      builder.makeCall(LOGGER, {builder.makeConst(static_cast<int32_t>(id++))}, Type::none),
       curr);
   }
 };
diff --git a/src/passes/Memory64Lowering.cpp b/src/passes/Memory64Lowering.cpp
index a387725..e4a4651 100644
--- a/src/passes/Memory64Lowering.cpp
+++ b/src/passes/Memory64Lowering.cpp
@@ -145,13 +145,13 @@
       auto tmp = builder.addVar(getFunction(), Type::i32);
       Expression* isMinusOne =
         builder.makeBinary(EqInt32,
-                           builder.makeConst(int32_t(-1)),
+                           builder.makeConst(static_cast<int32_t>(-1)),
                            builder.makeLocalTee(tmp, size, Type::i32));
       auto* newSize = builder.makeLocalGet(tmp, Type::i32);
       builder.makeUnary(UnaryOp::ExtendUInt32, newSize);
       Expression* ifExp =
         builder.makeIf(isMinusOne,
-                       builder.makeConst(int64_t(-1)),
+                       builder.makeConst(static_cast<int64_t>(-1)),
                        builder.makeUnary(UnaryOp::ExtendUInt32, newSize));
       curr->type = Type::i32;
       replaceCurrent(ifExp);
@@ -209,7 +209,7 @@
           memoryBase32 = builder
                            .makeGlobal(MEMORY_BASE32,
                                        Type::i32,
-                                       builder.makeConst(int32_t(0)),
+                                       builder.makeConst(static_cast<int32_t>(0)),
                                        Builder::Immutable)
                            .release();
           memoryBase32->module = g->module;
@@ -258,12 +258,12 @@
       auto tmp = builder.addVar(getFunction(), Type::i32);
       Expression* isMinusOne =
         builder.makeBinary(EqInt32,
-                           builder.makeConst(int32_t(-1)),
+                           builder.makeConst(static_cast<int32_t>(-1)),
                            builder.makeLocalTee(tmp, size, Type::i32));
       auto* newSize = builder.makeLocalGet(tmp, Type::i32);
       Expression* ifExp =
         builder.makeIf(isMinusOne,
-                       builder.makeConst(int64_t(-1)),
+                       builder.makeConst(static_cast<int64_t>(-1)),
                        builder.makeUnary(UnaryOp::ExtendUInt32, newSize));
       curr->type = Type::i32;
       replaceCurrent(ifExp);
@@ -317,7 +317,7 @@
           memoryBase32 = builder
                            .makeGlobal(TABLE_BASE32,
                                        Type::i32,
-                                       builder.makeConst(int32_t(0)),
+                                       builder.makeConst(static_cast<int32_t>(0)),
                                        Builder::Immutable)
                            .release();
           memoryBase32->module = g->module;
diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp
index 9d94492..2f87c15 100644
--- a/src/passes/MemoryPacking.cpp
+++ b/src/passes/MemoryPacking.cpp
@@ -697,7 +697,7 @@
       Names::getValidGlobalName(*module, "__mem_segment_drop_state");
     module->addGlobal(builder.makeGlobal(dropStateGlobal,
                                          Type::i32,
-                                         builder.makeConst(int32_t(0)),
+                                         builder.makeConst(static_cast<int32_t>(0)),
                                          Builder::Mutable));
     return dropStateGlobal;
   };
@@ -806,8 +806,8 @@
         appendResult(builder.makeMemoryFill(dest, value, size, init->memory));
       } else {
         size_t offsetBytes = std::max(start, range.start) - range.start;
-        Expression* offset = builder.makeConst(int32_t(offsetBytes));
-        Expression* size = builder.makeConst(int32_t(bytes));
+        Expression* offset = builder.makeConst(static_cast<int32_t>(offsetBytes));
+        Expression* size = builder.makeConst(static_cast<int32_t>(bytes));
         appendResult(builder.makeMemoryInit(
           segments[initIndex], dest, offset, size, init->memory));
         initIndex++;
@@ -845,7 +845,7 @@
     // Track drop state in a global only if some memory.init required it
     if (dropStateGlobal != Name()) {
       appendResult(
-        builder.makeGlobalSet(dropStateGlobal, builder.makeConst(int32_t(1))));
+        builder.makeGlobalSet(dropStateGlobal, builder.makeConst(static_cast<int32_t>(1))));
     }
     size_t dropIndex = 0;
     for (auto range : ranges) {
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp
index 3013f67..f45ac9d 100644
--- a/src/passes/MergeBlocks.cpp
+++ b/src/passes/MergeBlocks.cpp
@@ -356,7 +356,7 @@
       // For a loop, we may only be able to remove a tail
       if (loop) {
         auto childName = loop->name;
-        for (auto j = int(childSize - 1); j >= 0; j--) {
+        for (auto j = static_cast<int>(childSize - 1); j >= 0; j--) {
           auto* item = childList[j];
           if (BranchUtils::BranchSeeker::has(item, childName)) {
             // We can't remove this from the child.
diff --git a/src/passes/Monomorphize.cpp b/src/passes/Monomorphize.cpp
index 9f02d00..eedd687 100644
--- a/src/passes/Monomorphize.cpp
+++ b/src/passes/Monomorphize.cpp
@@ -373,7 +373,7 @@
     // moving.
     std::unordered_set<Expression*> immovable;
     EffectAnalyzer nonMovingEffects(options, wasm);
-    for (auto i = int64_t(lister.list.size()) - 1; i >= 0; i--) {
+    for (auto i = static_cast<int64_t>(lister.list.size()) - 1; i >= 0; i--) {
       auto* curr = lister.list[i];
 
       // This may have been marked as immovable because of the parent. We do
diff --git a/src/passes/MultiMemoryLowering.cpp b/src/passes/MultiMemoryLowering.cpp
index 7a10641..2218c47 100644
--- a/src/passes/MultiMemoryLowering.cpp
+++ b/src/passes/MultiMemoryLowering.cpp
@@ -529,7 +529,7 @@
       assert(offset && "TODO: handle non-const segment offsets");
       size_t originalOffset = offset->value.getUnsigned();
       auto memOffset = getInitialOffset(idx);
-      offset->value = Literal(int32_t(originalOffset + memOffset));
+      offset->value = Literal(static_cast<int32_t>(originalOffset + memOffset));
     });
   }
 
diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp
index fd58408..f6f3f12 100644
--- a/src/passes/OptimizeAddedConstants.cpp
+++ b/src/passes/OptimizeAddedConstants.cpp
@@ -161,8 +161,8 @@
       } else {
         uint32_t base = c->value.geti32();
         uint32_t offset = curr->offset;
-        if (uint64_t(base) + uint64_t(offset) < (uint64_t(1) << 32)) {
-          c->value = c->value.add(Literal(uint32_t(curr->offset)));
+        if (static_cast<uint64_t>(base) + static_cast<uint64_t>(offset) < (static_cast<uint64_t>(1) << 32)) {
+          c->value = c->value.add(Literal(static_cast<uint32_t>(curr->offset)));
           curr->offset = 0;
         }
       }
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 770cf75..7ee0dd4 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -580,7 +580,7 @@
         }
       }
       {
-        // unsigned(x) >= 0   =>   i32(1)
+        // static_cast<unsigned>(x) >= 0   =>   i32(1)
         Const* c;
         Expression* x;
         if (matches(curr, binary(GeU, any(&x), ival(&c))) &&
@@ -589,7 +589,7 @@
           c->type = Type::i32;
           return replaceCurrent(getDroppedChildrenAndAppend(curr, c));
         }
-        // unsigned(x) < 0   =>   i32(0)
+        // static_cast<unsigned>(x) < 0   =>   i32(0)
         if (curr->op == Abstract::getBinary(curr->left->type, Abstract::LtU) &&
             (c = getFallthrough(curr->right)->dynCast<Const>()) &&
             c->value.isZero()) {
@@ -651,7 +651,7 @@
           uint32_t right = c->value.geti32();
           uint32_t numRelevantBits = 32 - bits + 1;
           uint32_t setRelevantBits =
-            Bits::popCount(right >> uint32_t(bits - 1));
+            Bits::popCount(right >> static_cast<uint32_t>(bits - 1));
           // If all the relevant bits on C are zero
           // then we can mask off the high bits instead of sign-extending x.
           // This is valid because if x is negative, then the comparison was
@@ -788,14 +788,14 @@
           curr->op = c == -1 ? EqInt32 : GeUInt32;
           return replaceCurrent(curr);
         }
-        if (Bits::isPowerOf2((uint32_t)c)) {
+        if (Bits::isPowerOf2(static_cast<uint32_t>(c))) {
           switch (curr->op) {
             case MulInt32:
-              return replaceCurrent(optimizePowerOf2Mul(curr, (uint32_t)c));
+              return replaceCurrent(optimizePowerOf2Mul(curr, static_cast<uint32_t>(c)));
             case RemUInt32:
-              return replaceCurrent(optimizePowerOf2URem(curr, (uint32_t)c));
+              return replaceCurrent(optimizePowerOf2URem(curr, static_cast<uint32_t>(c)));
             case DivUInt32:
-              return replaceCurrent(optimizePowerOf2UDiv(curr, (uint32_t)c));
+              return replaceCurrent(optimizePowerOf2UDiv(curr, static_cast<uint32_t>(c)));
             default:
               break;
           }
@@ -822,14 +822,14 @@
           return replaceCurrent(
             Builder(*getModule()).makeUnary(ExtendUInt32, curr));
         }
-        if (Bits::isPowerOf2((uint64_t)c)) {
+        if (Bits::isPowerOf2(static_cast<uint64_t>(c))) {
           switch (curr->op) {
             case MulInt64:
-              return replaceCurrent(optimizePowerOf2Mul(curr, (uint64_t)c));
+              return replaceCurrent(optimizePowerOf2Mul(curr, static_cast<uint64_t>(c)));
             case RemUInt64:
-              return replaceCurrent(optimizePowerOf2URem(curr, (uint64_t)c));
+              return replaceCurrent(optimizePowerOf2URem(curr, static_cast<uint64_t>(c)));
             case DivUInt64:
-              return replaceCurrent(optimizePowerOf2UDiv(curr, (uint64_t)c));
+              return replaceCurrent(optimizePowerOf2UDiv(curr, static_cast<uint64_t>(c)));
             default:
               break;
           }
@@ -1303,7 +1303,7 @@
     //    (i32|i64).store(8|16|32)(p, C & mask)
     if (auto* c = value->dynCast<Const>()) {
       if (value->type == Type::i64 && bytes == 4) {
-        c->value = c->value.and_(Literal(uint64_t(0xffffffff)));
+        c->value = c->value.and_(Literal(static_cast<uint64_t>(0xffffffff)));
       } else {
         c->value = c->value.and_(
           Literal::makeFromInt32(Bits::lowBitMask(bytes * 8), value->type));
@@ -2215,7 +2215,7 @@
         // They are all equal to the default. Drop the children and return an
         // array.new_with_default.
         auto* withDefault = builder.makeArrayNew(
-          curr->type.getHeapType(), builder.makeConst(int32_t(size)));
+          curr->type.getHeapType(), builder.makeConst(static_cast<int32_t>(size)));
         replaceCurrent(getDroppedChildrenAndAppend(curr, withDefault));
         return;
       }
@@ -2249,7 +2249,7 @@
       curr, getFunction(), *getModule(), getPassOptions());
     auto* block = localizer.getChildrenReplacement();
     auto* arrayNew = builder.makeArrayNew(curr->type.getHeapType(),
-                                          builder.makeConst(int32_t(size)),
+                                          builder.makeConst(static_cast<int32_t>(size)),
                                           curr->values[0]);
     block->list.push_back(arrayNew);
     block->finalize();
@@ -2594,7 +2594,7 @@
         break;
       case GCTypeUtils::Success:
         replaceCurrent(builder.makeBlock(
-          {builder.makeDrop(curr->ref), builder.makeConst(int32_t(1))}));
+          {builder.makeDrop(curr->ref), builder.makeConst(static_cast<int32_t>(1))}));
         return;
       case GCTypeUtils::Unreachable:
         // Make sure to emit a block with the same type as us, to avoid other
@@ -2606,7 +2606,7 @@
         return;
       case GCTypeUtils::Failure:
         replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref),
-                                            builder.makeConst(int32_t(0))));
+                                            builder.makeConst(static_cast<int32_t>(0))));
         return;
       case GCTypeUtils::SuccessOnlyIfNull:
         replaceCurrent(builder.makeRefIsNull(curr->ref));
@@ -2976,14 +2976,14 @@
         c->value = Literal::makeZero(c->type);
         return;
       }
-      // (unsigned)x < 1   ==>   x == 0
+      // static_cast<unsigned>(x) < 1   ==>   x == 0
       if (binary->op == Abstract::getBinary(c->type, Abstract::LtU) &&
           c->value.getInteger() == 1LL) {
         binary->op = Abstract::getBinary(c->type, Abstract::Eq);
         c->value = Literal::makeZero(c->type);
         return;
       }
-      // (unsigned)x >= 1   ==>   x != 0
+      // static_cast<unsigned>(x) >= 1   ==>   x != 0
       if (binary->op == Abstract::getBinary(c->type, Abstract::GeU) &&
           c->value.getInteger() == 1LL) {
         binary->op = Abstract::getBinary(c->type, Abstract::Ne);
@@ -3037,16 +3037,16 @@
         return;
       }
       // Prefer compare to unsigned max (u_max) instead of u_max - 1.
-      // (unsigned)x <= u_max - 1   ==>   x != u_max
+      // static_cast<unsigned>(x) <= u_max - 1   ==>   x != u_max
       if (binary->op == Abstract::getBinary(c->type, Abstract::LeU) &&
-          c->value.getInteger() == (int64_t)(UINT64_MAX - 1)) {
+          c->value.getInteger() == static_cast<int64_t>(UINT64_MAX - 1)) {
         binary->op = Abstract::getBinary(c->type, Abstract::Ne);
         c->value = Literal::makeUnsignedMax(c->type);
         return;
       }
-      // (unsigned)x > u_max - 1   ==>   x == u_max
+      // static_cast<unsigned>(x) > u_max - 1   ==>   x == u_max
       if (binary->op == Abstract::getBinary(c->type, Abstract::GtU) &&
-          c->value.getInteger() == (int64_t)(UINT64_MAX - 1)) {
+          c->value.getInteger() == static_cast<int64_t>(UINT64_MAX - 1)) {
         binary->op = Abstract::getBinary(c->type, Abstract::Eq);
         c->value = Literal::makeUnsignedMax(c->type);
         return;
@@ -3425,11 +3425,11 @@
                    Abstract::getBinary(binary->type, Abstract::Mul)) {
           if (auto* c = binary->left->dynCast<Const>()) {
             seekStack.emplace_back(binary->right,
-                                   mul * (uint64_t)c->value.getInteger());
+                                   mul * c->value.getInteger());
             continue;
           } else if (auto* c = binary->right->dynCast<Const>()) {
             seekStack.emplace_back(binary->left,
-                                   mul * (uint64_t)c->value.getInteger());
+                                   mul * c->value.getInteger());
             continue;
           }
         }
@@ -3539,8 +3539,8 @@
   // being operated on behave the same with or without wrapping, then we don't
   // need to go to 64 bits at all, e.g.:
   //
-  //  int32_t(int64_t(x))               => x                 (extend, then wrap)
-  //  int32_t(int64_t(x) + int64_t(10)) => x + int32_t(10)            (also add)
+  //  static_cast<int32_t>(static_cast<int64_t>(x))               => x                 (extend, then wrap)
+  //  static_cast<int32_t>(static_cast<int64_t>(x) + static_cast<int64_t>(10)) => x + static_cast<int32_t>(10)            (also add)
   //
   Expression* optimizeWrappedResult(Unary* wrap) {
     assert(wrap->op == WrapInt64);
@@ -3569,7 +3569,7 @@
         } else if (auto* c = curr->dynCast<Const>()) {
           // A i64 const can be handled by just turning it into an i32.
           if (mode == Optimize) {
-            c->value = Literal(int32_t(c->value.getInteger()));
+            c->value = Literal(static_cast<int32_t>(c->value.getInteger()));
             c->type = Type::i32;
           }
         } else if (auto* unary = curr->dynCast<Unary>()) {
@@ -3704,10 +3704,10 @@
     Builder builder(*getModule());
     if (binary->op == OrInt32) {
       return builder.makeIf(
-        left, builder.makeConst(Literal(int32_t(1))), right);
+        left, builder.makeConst(Literal(static_cast<int32_t>(1))), right);
     } else { // &
       return builder.makeIf(
-        left, right, builder.makeConst(Literal(int32_t(0))));
+        left, right, builder.makeConst(Literal(static_cast<int32_t>(0))));
     }
   }
 
@@ -4017,16 +4017,16 @@
         // Check for a 64-bit overflow.
         uint64_t sum;
         if (!std::ckd_add(&sum, value64, offset64)) {
-          last->value = Literal(int64_t(sum));
+          last->value = Literal(static_cast<int64_t>(sum));
           offset = 0;
         }
       } else {
         // don't do this if it would wrap the pointer
-        if (value64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&
-            offset64 <= uint64_t(std::numeric_limits<int32_t>::max()) &&
+        if (value64 <= static_cast<uint64_t>(std::numeric_limits<int32_t>::max()) &&
+            offset64 <= static_cast<uint64_t>(std::numeric_limits<int32_t>::max()) &&
             value64 + offset64 <=
-              uint64_t(std::numeric_limits<int32_t>::max())) {
-          last->value = Literal(int32_t(value64 + offset64));
+              static_cast<uint64_t>(std::numeric_limits<int32_t>::max())) {
+          last->value = Literal(static_cast<int32_t>(value64 + offset64));
           offset = 0;
         }
       }
@@ -4094,7 +4094,7 @@
     static_assert(std::is_same<T, float>::value ||
                     std::is_same<T, double>::value,
                   "type mismatch");
-    double invDivisor = 1.0 / (double)c;
+    double invDivisor = 1.0 / static_cast<double>(c);
     binary->op = std::is_same<T, float>::value ? MulFloat32 : MulFloat64;
     binary->right->cast<Const>()->value = Literal(static_cast<T>(invDivisor));
     return binary;
@@ -4281,48 +4281,48 @@
       curr->type = Type::i32;
       return builder.makeUnary(ExtendUInt32, curr);
     }
-    // (unsigned)x < 0   ==>   i32(0)
+    // static_cast<unsigned>(x) < 0   ==>   i32(0)
     if (matches(curr, binary(LtU, pure(&left), ival(0)))) {
       right->value = Literal::makeZero(Type::i32);
       right->type = Type::i32;
       return right;
     }
-    // (unsigned)x <= -1  ==>   i32(1)
+    // static_cast<unsigned>(x) <= -1  ==>   i32(1)
     if (matches(curr, binary(LeU, any(&left), ival(-1)))) {
       right->value = Literal::makeOne(Type::i32);
       right->type = Type::i32;
       return getDroppedChildrenAndAppend(curr, right);
     }
-    // (unsigned)x > -1   ==>   i32(0)
+    // static_cast<unsigned>(x) > -1   ==>   i32(0)
     if (matches(curr, binary(GtU, any(&left), ival(-1)))) {
       right->value = Literal::makeZero(Type::i32);
       right->type = Type::i32;
       return getDroppedChildrenAndAppend(curr, right);
     }
-    // (unsigned)x >= 0   ==>   i32(1)
+    // static_cast<unsigned>(x) >= 0   ==>   i32(1)
     if (matches(curr, binary(GeU, pure(&left), ival(0)))) {
       right->value = Literal::makeOne(Type::i32);
       right->type = Type::i32;
       return right;
     }
-    // (unsigned)x < -1   ==>   x != -1
+    // static_cast<unsigned>(x) < -1   ==>   x != -1
     // Friendlier to JS emitting as we don't need to write an unsigned -1 value
     // which is large.
     if (matches(curr, binary(LtU, any(), ival(-1)))) {
       curr->op = Abstract::getBinary(type, Ne);
       return curr;
     }
-    // (unsigned)x <= 0   ==>   x == 0
+    // static_cast<unsigned>(x) <= 0   ==>   x == 0
     if (matches(curr, binary(LeU, any(), ival(0)))) {
       curr->op = Abstract::getBinary(type, Eq);
       return curr;
     }
-    // (unsigned)x > 0   ==>   x != 0
+    // static_cast<unsigned>(x) > 0   ==>   x != 0
     if (matches(curr, binary(GtU, any(), ival(0)))) {
       curr->op = Abstract::getBinary(type, Ne);
       return curr;
     }
-    // (unsigned)x >= -1  ==>   x == -1
+    // static_cast<unsigned>(x) >= -1  ==>   x == -1
     if (matches(curr, binary(GeU, any(), ival(-1)))) {
       curr->op = Abstract::getBinary(type, Eq);
       return curr;
@@ -4794,11 +4794,11 @@
       }
       // x - y == 0  =>  x == y
       // x - y != 0  =>  x != y
-      // unsigned(x - y) > 0    =>   x != y
-      // unsigned(x - y) <= 0   =>   x == y
+      // static_cast<unsigned>(x - y) > 0    =>   x != y
+      // static_cast<unsigned>(x - y) <= 0   =>   x == y
       {
         Binary* inner;
-        // unsigned(x - y) > 0    =>   x != y
+        // static_cast<unsigned>(x - y) > 0    =>   x != y
         if (matches(curr,
                     binary(GtU, binary(&inner, Sub, any(), any()), ival(0)))) {
           curr->op = Abstract::getBinary(type, Ne);
@@ -4806,7 +4806,7 @@
           curr->left = inner->left;
           return curr;
         }
-        // unsigned(x - y) <= 0   =>   x == y
+        // static_cast<unsigned>(x - y) <= 0   =>   x == y
         if (matches(curr,
                     binary(LeU, binary(&inner, Sub, any(), any()), ival(0)))) {
           curr->op = Abstract::getBinary(type, Eq);
@@ -4930,7 +4930,7 @@
       }
 
       // Comparisons can sometimes be simplified depending on the number of
-      // bits, e.g.  (unsigned)x > y  must be true if x has strictly more bits.
+      // bits, e.g.  static_cast<unsigned>(x) > y  must be true if x has strictly more bits.
       // A common case is a constant on the right, e.g. (x & 255) < 256 must be
       // true.
       // TODO: use getMinBits in more places, see ideas in
@@ -4948,8 +4948,8 @@
             // There are not enough bits on the left for it to be equal to the
             // right, making various comparisons obviously false:
             //             x == y
-            //   (unsigned)x >  y
-            //   (unsigned)x >= y
+            //   static_cast<unsigned>(x) >  y
+            //   static_cast<unsigned>(x) >= y
             // and the same for signed, if y does not have the sign bit set
             // (in that case, the comparison is effectively unsigned).
             //
@@ -4968,8 +4968,8 @@
 
             // And some are obviously true:
             //             x != y
-            //   (unsigned)x <  y
-            //   (unsigned)x <= y
+            //   static_cast<unsigned>(x) <  y
+            //   static_cast<unsigned>(x) <= y
             // and likewise for signed, as above.
             if (curr->op == Abstract::getBinary(type, Ne) ||
                 curr->op == Abstract::getBinary(type, LtU) ||
@@ -5041,10 +5041,10 @@
       case NearestFloat32:
       case NearestFloat64: {
         // Rounding after integer to float conversion may be skipped
-        //   ceil(float(int(x)))     ==>  float(int(x))
-        //   floor(float(int(x)))    ==>  float(int(x))
-        //   trunc(float(int(x)))    ==>  float(int(x))
-        //   nearest(float(int(x)))  ==>  float(int(x))
+        //   ceil(static_cast<float>(static_cast<int>(x)))     ==>  static_cast<float>(static_cast<int>(x))
+        //   floor(static_cast<float>(static_cast<int>(x)))    ==>  static_cast<float>(static_cast<int>(x))
+        //   trunc(static_cast<float>(static_cast<int>(x)))    ==>  static_cast<float>(static_cast<int>(x))
+        //   nearest(static_cast<float>(static_cast<int>(x)))  ==>  static_cast<float>(static_cast<int>(x))
         Unary* inner;
         if (matches(curr->value, unary(&inner, any()))) {
           switch (inner->op) {
@@ -5388,7 +5388,7 @@
           if (options.shrinkLevel == 0) {
             if (getModule()->features.hasSIMD()) {
               uint8_t values[16];
-              std::fill_n(values, 16, (uint8_t)value);
+              std::fill_n(values, 16, static_cast<uint8_t>(value));
               return builder.makeStore(16,
                                        offset,
                                        align,
diff --git a/src/passes/Outlining.cpp b/src/passes/Outlining.cpp
index 6a83fac..22c359b 100644
--- a/src/passes/Outlining.cpp
+++ b/src/passes/Outlining.cpp
@@ -124,11 +124,11 @@
 void HashStringifyWalker::addUniqueSymbol(SeparatorReason reason) {
   // Use a negative value to distinguish symbols for separators from symbols
   // for Expressions
-  assert((uint32_t)nextSeparatorVal >= nextVal);
+  assert(static_cast<uint32_t>(nextSeparatorVal) >= nextVal);
   if (auto funcStart = reason.getFuncStart()) {
     idxToFuncName.insert({hashString.size(), funcStart->func->name});
   }
-  hashString.push_back((uint32_t)nextSeparatorVal);
+  hashString.push_back(static_cast<uint32_t>(nextSeparatorVal));
   nextSeparatorVal--;
   exprs.push_back(nullptr);
 }
diff --git a/src/passes/Poppify.cpp b/src/passes/Poppify.cpp
index a7f3e5c..36b4468 100644
--- a/src/passes/Poppify.cpp
+++ b/src/passes/Poppify.cpp
@@ -332,7 +332,7 @@
   auto type = types[curr->index];
   Index scratch = getScratchLocal(type);
   instrs.push_back(builder.makeLocalSet(scratch, builder.makePop(type)));
-  for (size_t i = curr->index - 1; i != size_t(-1); --i) {
+  for (size_t i = curr->index - 1; i != static_cast<size_t>(-1); --i) {
     instrs.push_back(builder.makeDrop(builder.makePop(types[i])));
   }
   // Retrieve the saved value
diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp
index 7263066..963fb4a 100644
--- a/src/passes/PostEmscripten.cpp
+++ b/src/passes/PostEmscripten.cpp
@@ -72,7 +72,7 @@
 
 static void calcSegmentOffsets(Module& wasm,
                                std::vector<Address>& segmentOffsets) {
-  const Address UNKNOWN_OFFSET(uint32_t(-1));
+  const Address UNKNOWN_OFFSET(static_cast<uint32_t>(-1));
 
   std::unordered_map<Name, Address> passiveOffsets;
   if (wasm.features.hasBulkMemory()) {
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 7a7c1d1..d76cbcf 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -734,7 +734,7 @@
         break;
     }
     restoreNormalColor(o);
-    o << " " << int(curr->index);
+    o << " " << static_cast<int>(curr->index);
   }
   void visitSIMDReplace(SIMDReplace* curr) {
     prepareColor(o);
@@ -762,7 +762,7 @@
         break;
     }
     restoreNormalColor(o);
-    o << " " << int(curr->index);
+    o << " " << static_cast<int>(curr->index);
   }
   void visitSIMDShuffle(SIMDShuffle* curr) {
     prepareColor(o);
@@ -941,7 +941,7 @@
     if (curr->align != curr->getMemBytes()) {
       o << " align=" << curr->align;
     }
-    o << " " << int(curr->index);
+    o << " " << static_cast<int>(curr->index);
   }
   void visitMemoryInit(MemoryInit* curr) {
     prepareColor(o);
@@ -2205,7 +2205,7 @@
     // not a valid tuple size. The size we print mostly doesn't matter if the
     // tuple is unreachable, but it does have to be valid.
     o << std::max(
-           {curr->tuple->type.size(), size_t(2), size_t(curr->index + 1)})
+           {curr->tuple->type.size(), static_cast<size_t>(2), static_cast<size_t>(curr->index + 1)})
       << " ";
     o << curr->index;
   }
@@ -2804,7 +2804,7 @@
     std::ofstream saved;
     saved.copyfmt(o);
     o << "(@" << Annotations::InlineHint << " \"\\" << std::hex
-      << std::setfill('0') << std::setw(2) << int(*annotation.inline_)
+      << std::setfill('0') << std::setw(2) << static_cast<int>(*annotation.inline_)
       << "\")\n";
     o.copyfmt(saved);
     restoreNormalColor(o);
diff --git a/src/passes/ReReloop.cpp b/src/passes/ReReloop.cpp
index cdd6b3a..baddaf5 100644
--- a/src/passes/ReReloop.cpp
+++ b/src/passes/ReReloop.cpp
@@ -134,7 +134,7 @@
         parent.stack.push_back(task);
       }
       auto& list = curr->list;
-      for (int i = int(list.size()) - 1; i >= 0; i--) {
+      for (int i = static_cast<int>(list.size()) - 1; i >= 0; i--) {
         parent.stack.push_back(std::make_shared<TriageTask>(parent, list[i]));
       }
     }
@@ -322,8 +322,8 @@
       auto* block = cfgBlock->Code->cast<Block>();
       if (cfgBlock->BranchesOut.empty() && block->type != Type::unreachable) {
         block->list.push_back(function->getResults() == Type::none
-                                ? (Expression*)builder->makeReturn()
-                                : (Expression*)builder->makeUnreachable());
+                                ? static_cast<Expression*>(builder->makeReturn())
+                                : static_cast<Expression*>(builder->makeUnreachable()));
         block->finalize();
       }
     }
diff --git a/src/passes/RemoveNonJSOps.cpp b/src/passes/RemoveNonJSOps.cpp
index 8af0d10..65716db 100644
--- a/src/passes/RemoveNonJSOps.cpp
+++ b/src/passes/RemoveNonJSOps.cpp
@@ -270,8 +270,8 @@
         int2float = ReinterpretInt32;
         bitAnd = AndInt32;
         bitOr = OrInt32;
-        signBit = Literal(uint32_t(1U << 31));
-        otherBits = Literal(~uint32_t(1U << 31));
+        signBit = Literal(static_cast<uint32_t>(1U << 31));
+        otherBits = Literal(~static_cast<uint32_t>(1U << 31));
         break;
 
       case CopySignFloat64:
@@ -279,8 +279,8 @@
         int2float = ReinterpretInt64;
         bitAnd = AndInt64;
         bitOr = OrInt64;
-        signBit = Literal(uint64_t(1ULL << 63));
-        otherBits = Literal(~uint64_t(1ULL << 63));
+        signBit = Literal(static_cast<uint64_t>(1ULL << 63));
+        otherBits = Literal(~static_cast<uint64_t>(1ULL << 63));
         break;
 
       default:
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index d081c51..cc43deb 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -332,7 +332,7 @@
       curr->targets.resize(curr->targets.size() - removable);
       Builder builder(*getModule());
       curr->condition = builder.makeBinary(
-        SubInt32, curr->condition, builder.makeConst(int32_t(removable)));
+        SubInt32, curr->condition, builder.makeConst(static_cast<int32_t>(removable)));
     }
     // when there isn't a value, we can do some trivial optimizations without
     // worrying about the value being executed before the condition
@@ -387,7 +387,7 @@
                                           EqInt32,
                                           builder.makeLocalGet(temp, Type::i32),
                                           builder.makeConst(
-                                            int32_t(curr->targets.size() - 1))),
+                                            static_cast<int32_t>(curr->targets.size() - 1))),
                                         builder.makeBreak(curr->targets.back()),
                                         builder.makeBreak(curr->default_)),
                          builder.makeBreak(curr->targets.front())));
@@ -478,7 +478,7 @@
         }
         Builder builder(*getModule());
         curr->condition = builder.makeSelect(
-          child->condition, curr->condition, builder.makeConst(int32_t(0)));
+          child->condition, curr->condition, builder.makeConst(static_cast<int32_t>(0)));
         BranchHints::applyAndTo(curr, child, curr, getFunction());
         curr->ifTrue = child->ifTrue;
       }
@@ -1891,7 +1891,7 @@
             return nullptr;
           }
           uint32_t value = c->value.geti32();
-          if (value >= uint32_t(std::numeric_limits<int32_t>::max())) {
+          if (value >= static_cast<uint32_t>(std::numeric_limits<int32_t>::max())) {
             return nullptr;
           }
           return br;
@@ -2016,7 +2016,7 @@
 
               if (min != 0) {
                 newCondition = builder.makeBinary(
-                  SubInt32, newCondition, builder.makeConst(int32_t(min)));
+                  SubInt32, newCondition, builder.makeConst(static_cast<int32_t>(min)));
               }
               list[end - 1] = builder.makeBlock(
                 defaultName,
diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp
index f81dc60..0c7066f 100644
--- a/src/passes/SafeHeap.cpp
+++ b/src/passes/SafeHeap.cpp
@@ -421,7 +421,7 @@
     }
     return builder.makeIf(
       builder.makeBinary(
-        AndInt32, ptrBits, builder.makeConst(int32_t(align - 1))),
+        AndInt32, ptrBits, builder.makeConst(static_cast<int32_t>(align - 1))),
       builder.makeCall(alignfault, {}, Type::none));
   }
 
diff --git a/src/passes/SetGlobals.cpp b/src/passes/SetGlobals.cpp
index 4c0718e..fd101cd 100644
--- a/src/passes/SetGlobals.cpp
+++ b/src/passes/SetGlobals.cpp
@@ -46,9 +46,9 @@
       // Parse the input.
       Literal lit;
       if (glob->type == Type::i32) {
-        lit = Literal(int32_t(stoi(value)));
+        lit = Literal(static_cast<int32_t>(stoi(value)));
       } else if (glob->type == Type::i64) {
-        lit = Literal(int64_t(stoll(value)));
+        lit = Literal(static_cast<int64_t>(stoll(value)));
       } else {
         Fatal() << "global's type is not supported: " << name;
       }
diff --git a/src/passes/SignExtLowering.cpp b/src/passes/SignExtLowering.cpp
index 659dc4b..e9c6584 100644
--- a/src/passes/SignExtLowering.cpp
+++ b/src/passes/SignExtLowering.cpp
@@ -50,19 +50,19 @@
   void visitUnary(Unary* curr) {
     switch (curr->op) {
       case ExtendS8Int32:
-        lowerToShifts(curr->value, ShlInt32, ShrSInt32, int32_t(8));
+        lowerToShifts(curr->value, ShlInt32, ShrSInt32, static_cast<int32_t>(8));
         break;
       case ExtendS16Int32:
-        lowerToShifts(curr->value, ShlInt32, ShrSInt32, int32_t(16));
+        lowerToShifts(curr->value, ShlInt32, ShrSInt32, static_cast<int32_t>(16));
         break;
       case ExtendS8Int64:
-        lowerToShifts(curr->value, ShlInt64, ShrSInt64, int64_t(8));
+        lowerToShifts(curr->value, ShlInt64, ShrSInt64, static_cast<int64_t>(8));
         break;
       case ExtendS16Int64:
-        lowerToShifts(curr->value, ShlInt64, ShrSInt64, int64_t(16));
+        lowerToShifts(curr->value, ShlInt64, ShrSInt64, static_cast<int64_t>(16));
         break;
       case ExtendS32Int64:
-        lowerToShifts(curr->value, ShlInt64, ShrSInt64, int64_t(32));
+        lowerToShifts(curr->value, ShlInt64, ShrSInt64, static_cast<int64_t>(32));
         break;
       default: {
       }
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp
index 4cd44b1..1a03453 100644
--- a/src/passes/SimplifyGlobals.cpp
+++ b/src/passes/SimplifyGlobals.cpp
@@ -246,7 +246,7 @@
             // We found the get of the global. Check where its value flows to,
             // and how it is used there.
             assert(expressionStack.back() == get);
-            for (int i = int(expressionStack.size()) - 2; i >= 0; i--) {
+            for (int i = static_cast<int>(expressionStack.size()) - 2; i >= 0; i--) {
               // Consider one pair of parent->child, and check if the parent
               // causes any problems when the child's value reaches it.
               auto* parent = expressionStack[i];
diff --git a/src/passes/SpillPointers.cpp b/src/passes/SpillPointers.cpp
index cfa432a..76dbcf7 100644
--- a/src/passes/SpillPointers.cpp
+++ b/src/passes/SpillPointers.cpp
@@ -112,7 +112,7 @@
       // scan through the block, spilling around the calls
       // TODO: we can filter on pointerMap everywhere
       SetOfLocals live = liveness.end;
-      for (int i = int(actions.size()) - 1; i >= 0; i--) {
+      for (int i = static_cast<int>(actions.size()) - 1; i >= 0; i--) {
         auto& action = actions[i];
         if (action.isGet()) {
           live.insert(action.index);
diff --git a/src/passes/TrapMode.cpp b/src/passes/TrapMode.cpp
index 8438b74..e4ee950 100644
--- a/src/passes/TrapMode.cpp
+++ b/src/passes/TrapMode.cpp
@@ -117,11 +117,11 @@
   UnaryOp eqZOp = isI64 ? EqZInt64 : EqZInt32;
   Literal minLit = isI64 ? Literal(std::numeric_limits<int64_t>::min())
                          : Literal(std::numeric_limits<int32_t>::min());
-  Literal zeroLit = isI64 ? Literal(int64_t(0)) : Literal(int32_t(0));
+  Literal zeroLit = isI64 ? Literal(static_cast<int64_t>(0)) : Literal(static_cast<int32_t>(0));
   if (op == divSIntOp) {
     // guard against signed division overflow
     BinaryOp eqOp = isI64 ? EqInt64 : EqInt32;
-    Literal negLit = isI64 ? Literal(int64_t(-1)) : Literal(int32_t(-1));
+    Literal negLit = isI64 ? Literal(static_cast<int64_t>(-1)) : Literal(static_cast<int32_t>(-1));
     result = builder.makeIf(
       builder.makeBinary(
         AndInt32,
diff --git a/src/passes/TypeMerging.cpp b/src/passes/TypeMerging.cpp
index 5ca40ca..6bfd507 100644
--- a/src/passes/TypeMerging.cpp
+++ b/src/passes/TypeMerging.cpp
@@ -772,8 +772,8 @@
 }
 
 size_t shapeHash(Field a) {
-  auto digest = hash((int)a.packedType);
-  rehash(digest, (int)a.mutable_);
+  auto digest = hash(a.packedType);
+  rehash(digest, a.mutable_);
   hash_combine(digest, shapeHash(a.type));
   return digest;
 }
@@ -840,8 +840,8 @@
     return digest;
   }
   rehash(digest, 4);
-  rehash(digest, (int)a.getNullability());
-  rehash(digest, (int)a.getExactness());
+  rehash(digest, a.getNullability());
+  rehash(digest, a.getExactness());
   rehash(digest, chainIndex(a.getHeapType()));
   return digest;
 }
diff --git a/src/support/archive.cpp b/src/support/archive.cpp
index 1704fd8..6d08096 100644
--- a/src/support/archive.cpp
+++ b/src/support/archive.cpp
@@ -49,8 +49,7 @@
   if (!end) {
     end = fileName + sizeof(fileName);
   }
-  return std::string((char*)(fileName), end - fileName);
-}
+  return std::string(reinterpret_cast<const char*>(fileName), end - fileName);}
 
 uint32_t ArchiveMemberHeader::getSize() const {
   auto* end = static_cast<const char*>(memchr(size, ' ', sizeof(size)));
@@ -145,7 +144,7 @@
 Archive::Child Archive::Child::getNext(bool& error) const {
   // Members are aligned to even byte boundaries.
   uint32_t nextOffset = len + (len & 1);
-  if ((size_t)(data - (const uint8_t*)parent->data.data() + nextOffset) >=
+  if (static_cast<size_t>(data - (const uint8_t*)parent->data.data() + nextOffset) >=
       parent->data.size()) { // End of the archive.
     return Child();
   }
@@ -167,7 +166,7 @@
     int offset = std::stoi(name.substr(1), nullptr, 10);
 
     // Verify it.
-    if (offset < 0 || (unsigned)offset >= parent->stringTable.len) {
+    if (offset < 0 || static_cast<unsigned>(offset) >= parent->stringTable.len) {
       wasm::Fatal() << "Malformed archive: name parsing failed\n";
     }
 
@@ -210,8 +209,8 @@
   uint32_t stringIndex;
   void next(Archive::SubBuffer& symbolTable) {
     // Symbol table entries are NUL-terminated. Skip past the next NUL.
-    stringIndex = strchr((char*)symbolTable.data + stringIndex, '\0') -
-                  (char*)symbolTable.data + 1;
+    stringIndex = strchr(reinterpret_cast<const char*>(symbolTable.data) + stringIndex, '\0') -
+                  reinterpret_cast<const char*>(symbolTable.data) + 1;
     ++symbolIndex;
   }
 };
diff --git a/src/support/base64.h b/src/support/base64.h
index 8634246..e65b2a6 100644
--- a/src/support/base64.h
+++ b/src/support/base64.h
@@ -30,9 +30,9 @@
                          "0123456789+/";
 
   while (i + 3 <= data.size()) {
-    uint32_t bits = (((uint32_t)(uint8_t)data[i + 0]) << 16) |
-                    (((uint32_t)(uint8_t)data[i + 1]) << 8) |
-                    (((uint32_t)(uint8_t)data[i + 2]) << 0);
+    uint32_t bits = ((static_cast<uint32_t>(static_cast<uint8_t>(data[i + 0]))) << 16) |
+                    ((static_cast<uint32_t>(static_cast<uint8_t>(data[i + 1]))) << 8) |
+                    ((static_cast<uint32_t>(static_cast<uint8_t>(data[i + 2]))) << 0);
     ret += alphabet[(bits >> 18) & 0x3f];
     ret += alphabet[(bits >> 12) & 0x3f];
     ret += alphabet[(bits >> 6) & 0x3f];
@@ -41,14 +41,14 @@
   }
 
   if (i + 2 == data.size()) {
-    uint32_t bits = (((uint32_t)(uint8_t)data[i + 0]) << 8) |
-                    (((uint32_t)(uint8_t)data[i + 1]) << 0);
+    uint32_t bits = ((static_cast<uint32_t>(static_cast<uint8_t>(data[i + 0]))) << 8) |
+                    ((static_cast<uint32_t>(static_cast<uint8_t>(data[i + 1]))) << 0);
     ret += alphabet[(bits >> 10) & 0x3f];
     ret += alphabet[(bits >> 4) & 0x3f];
     ret += alphabet[(bits << 2) & 0x3f];
     ret += '=';
   } else if (i + 1 == data.size()) {
-    uint32_t bits = (uint32_t)(uint8_t)data[i + 0];
+    uint32_t bits = static_cast<uint32_t>(static_cast<uint8_t>(data[i + 0]));
     ret += alphabet[(bits >> 2) & 0x3f];
     ret += alphabet[(bits << 4) & 0x3f];
     ret += '=';
diff --git a/src/support/bits.cpp b/src/support/bits.cpp
index aa24eda..35a1ecd 100644
--- a/src/support/bits.cpp
+++ b/src/support/bits.cpp
@@ -36,7 +36,7 @@
 #if __has_builtin(__builtin_popcount) || defined(__GNUC__)
   return __builtin_popcount(v);
 #else
-  return popCount((uint8_t)(v & 0xFF)) + popCount((uint8_t)(v >> 8));
+  return popCount(static_cast<uint8_t>(v & 0xFF)) + popCount(static_cast<uint8_t>(v >> 8));
 #endif
 }
 
@@ -56,7 +56,7 @@
 #if __has_builtin(__builtin_popcount) || defined(__GNUC__)
   return __builtin_popcountll(v);
 #else
-  return popCount((uint32_t)v) + popCount((uint32_t)(v >> 32));
+  return popCount(static_cast<uint32_t>(v)) + popCount(static_cast<uint32_t>(v >> 32));
 #endif
 }
 
@@ -78,7 +78,7 @@
 #elif defined(_MSC_VER)
   unsigned long count;
   _BitScanForward(&count, v);
-  return (int)count;
+  return static_cast<int>(count);
 #else
   // See Stanford bithacks, count the consecutive zero bits (trailing) on the
   // right with multiply and lookup:
@@ -86,7 +86,7 @@
   static const uint8_t tbl[32] = {0,  1,  28, 2,  29, 14, 24, 3,  30, 22, 20,
                                   15, 25, 17, 4,  8,  31, 27, 13, 23, 21, 19,
                                   16, 7,  26, 12, 18, 6,  11, 5,  10, 9};
-  return (int)tbl[((uint32_t)((v & -v) * 0x077CB531U)) >> 27];
+  return tbl[(static_cast<uint32_t>((v & -v) * 0x077CB531U)) >> 27];
 #endif
 }
 
@@ -99,10 +99,10 @@
 #elif defined(_MSC_VER) && defined(_M_X64)
   unsigned long count;
   _BitScanForward64(&count, v);
-  return (int)count;
+  return static_cast<int>(count);
 #else
-  return (uint32_t)v ? countTrailingZeroes((uint32_t)v)
-                     : 32 + countTrailingZeroes((uint32_t)(v >> 32));
+  return static_cast<uint32_t>(v) ? countTrailingZeroes(static_cast<uint32_t>(v))
+                     : 32 + countTrailingZeroes(static_cast<uint32_t>(v >> 32));
 #endif
 }
 
@@ -118,7 +118,7 @@
   // BitScanReverse gives the bit position (0 for the LSB, then 1, etc.) of the
   // first bit that is 1, when looking from the MSB. To count leading zeros, we
   // need to adjust that.
-  return 31 - int(count);
+  return 31 - static_cast<int>(count);
 #else
   // See Stanford bithacks, find the log base 2 of an N-bit integer in
   // O(lg(N)) operations with multiply and lookup:
@@ -131,7 +131,7 @@
   v = v | (v >> 4);
   v = v | (v >> 8);
   v = v | (v >> 16);
-  return (int)tbl[((uint32_t)(v * 0x07C4ACDDU)) >> 27];
+  return tbl[(static_cast<uint32_t>(v * 0x07C4ACDDU)) >> 27];
 #endif
 }
 
@@ -144,10 +144,10 @@
 #elif defined(_MSC_VER) && defined(_M_X64)
   unsigned long count;
   _BitScanReverse64(&count, v);
-  return 63 - int(count);
+  return 63 - static_cast<int>(count);
 #else
-  return v >> 32 ? countLeadingZeroes((uint32_t)(v >> 32))
-                 : 32 + countLeadingZeroes((uint32_t)v);
+  return v >> 32 ? countLeadingZeroes(static_cast<uint32_t>(v >> 32))
+                 : 32 + countLeadingZeroes(static_cast<uint32_t>(v));
 #endif
 }
 
@@ -178,7 +178,7 @@
 }
 
 bool isPowerOf2InvertibleFloat(double v) {
-  // See isPowerOf2InvertibleFloat(float)
+  // See isPowerOf2InvertibleFloat(float v)
   const uint64_t MIN_POT = 0x001ULL << 52;  // 0x1p-1022
   const uint64_t MAX_POT = 0x7FDULL << 52;  // 0x1p+1022
   const uint64_t EXP_MASK = 0x7FFULL << 52; // mask only exponent
diff --git a/src/support/bits.h b/src/support/bits.h
index 9c68a7a..a64e41e 100644
--- a/src/support/bits.h
+++ b/src/support/bits.h
@@ -38,10 +38,10 @@
 int popCount(uint32_t);
 int popCount(uint64_t);
 
-inline int popCount(int8_t v) { return popCount(uint8_t(v)); }
-inline int popCount(int16_t v) { return popCount(uint16_t(v)); }
-inline int popCount(int32_t v) { return popCount(uint32_t(v)); }
-inline int popCount(int64_t v) { return popCount(uint64_t(v)); }
+inline int popCount(int8_t v) { return popCount(static_cast<uint8_t>(v)); }
+inline int popCount(int16_t v) { return popCount(static_cast<uint16_t>(v)); }
+inline int popCount(int32_t v) { return popCount(static_cast<uint32_t>(v)); }
+inline int popCount(int64_t v) { return popCount(static_cast<uint64_t>(v)); }
 
 uint32_t bitReverse(uint32_t);
 
@@ -49,27 +49,27 @@
 int countTrailingZeroes(uint64_t);
 
 inline int countTrailingZeroes(int32_t v) {
-  return countTrailingZeroes(uint32_t(v));
+  return countTrailingZeroes(static_cast<uint32_t>(v));
 }
 inline int countTrailingZeroes(int64_t v) {
-  return countTrailingZeroes(uint64_t(v));
+  return countTrailingZeroes(static_cast<uint64_t>(v));
 }
 
 int countLeadingZeroes(uint32_t);
 int countLeadingZeroes(uint64_t);
 
 inline int countLeadingZeroes(int32_t v) {
-  return countLeadingZeroes(uint32_t(v));
+  return countLeadingZeroes(static_cast<uint32_t>(v));
 }
 inline int countLeadingZeroes(int64_t v) {
-  return countLeadingZeroes(uint64_t(v));
+  return countLeadingZeroes(static_cast<uint64_t>(v));
 }
 
 int ceilLog2(uint32_t);
 int ceilLog2(uint64_t);
 
-inline int ceilLog2(int32_t v) { return ceilLog2(uint32_t(v)); }
-inline int ceilLog2(int64_t v) { return ceilLog2(uint64_t(v)); }
+inline int ceilLog2(int32_t v) { return ceilLog2(static_cast<uint32_t>(v)); }
+inline int ceilLog2(int64_t v) { return ceilLog2(static_cast<uint64_t>(v)); }
 
 template<typename T> bool isPowerOf2(T v) {
   return v != 0 && (v & (v - 1)) == 0;
diff --git a/src/support/command-line.cpp b/src/support/command-line.cpp
index 30db3f4..5e22692 100644
--- a/src/support/command-line.cpp
+++ b/src/support/command-line.cpp
@@ -107,7 +107,7 @@
           optionWidth =
             std::max(optionWidth, o.longName.size() + o.shortName.size());
         }
-        for (int i = int(categories.size()) - 1; i >= 0; i--) {
+        for (int i = static_cast<int>(categories.size()) - 1; i >= 0; i--) {
           auto& category = categories[i];
           std::cout << "\n\n" << category << ":\n";
           for (size_t i = 0; i < category.size() + 1; i++) {
diff --git a/src/support/file.cpp b/src/support/file.cpp
index 918ab29..96de686 100644
--- a/src/support/file.cpp
+++ b/src/support/file.cpp
@@ -66,7 +66,7 @@
   }
   infile.seekg(0, std::ios::end);
   std::streampos insize = infile.tellg();
-  if (uint64_t(insize) >= std::numeric_limits<size_t>::max()) {
+  if (static_cast<uint64_t>(insize) >= std::numeric_limits<size_t>::max()) {
     // Building a 32-bit executable where size_t == 32 bits, we are not able to
     // create strings larger than 2^32 bytes in length, so must abort here.
     Fatal() << "Failed opening '" << filename
@@ -74,14 +74,14 @@
             << " bytes. Try rebuilding in 64-bit mode.";
   }
   // Zero-initialize the string or vector with the expected size.
-  T input(size_t(insize), '\0');
-  if (size_t(insize) == 0) {
+  T input(static_cast<size_t>(insize), '\0');
+  if (static_cast<size_t>(insize) == 0) {
     return input;
   }
   infile.seekg(0);
   infile.read(&input[0], insize);
   if (binary == Flags::Text) {
-    size_t chars = size_t(infile.gcount());
+    size_t chars = static_cast<size_t>(infile.gcount());
     // Truncate size to the number of ASCII characters actually read in text
     // mode (which is generally less than the number of bytes on Windows, if
     // \r\n line endings are present)
diff --git a/src/support/istring.cpp b/src/support/istring.cpp
index 60c8b59..47bc665 100644
--- a/src/support/istring.cpp
+++ b/src/support/istring.cpp
@@ -73,7 +73,7 @@
     // We have a new string, but it doesn't have a stable address. Create a copy
     // of the data at a stable address we can use. Make sure it is null
     // terminated so legacy uses that get a C string still work.
-    char* data = (char*)arena.allocSpace(s.size() + 1, 1);
+    char* data = static_cast<char*>(arena.allocSpace(s.size() + 1, 1));
     std::copy(s.begin(), s.end(), data);
     data[s.size()] = '\0';
     s = std::string_view(data, s.size());
diff --git a/src/support/istring.h b/src/support/istring.h
index dad20b8..2ffdd26 100644
--- a/src/support/istring.h
+++ b/src/support/istring.h
@@ -115,7 +115,7 @@
 
 template<> struct hash<wasm::IString> {
   size_t operator()(const wasm::IString& str) const {
-    return std::hash<size_t>{}(uintptr_t(str.str.data()));
+    return std::hash<size_t>{}(reinterpret_cast<uintptr_t>(str.str.data()));
   }
 };
 
diff --git a/src/support/json.h b/src/support/json.h
index 23d0749..74e8ceb 100644
--- a/src/support/json.h
+++ b/src/support/json.h
@@ -210,7 +210,7 @@
   int32_t getInteger() { // convenience function to get a known integer
     assert(wasm::isInteger(getNumber()));
     int32_t ret = getNumber();
-    assert(double(ret) == getNumber()); // no loss in conversion
+    assert(static_cast<double>(ret) == getNumber()); // no loss in conversion
     return ret;
   }
 
diff --git a/src/support/safe_integer.cpp b/src/support/safe_integer.cpp
index 86ba254..bfa6b67 100644
--- a/src/support/safe_integer.cpp
+++ b/src/support/safe_integer.cpp
@@ -37,14 +37,14 @@
 uint32_t wasm::toUInteger32(double x) {
   return std::signbit(x) ? 0
                          : (x < std::numeric_limits<uint32_t>::max()
-                              ? (uint32_t)x
+                              ? static_cast<uint32_t>(x)
                               : std::numeric_limits<uint32_t>::max());
 }
 
 int32_t wasm::toSInteger32(double x) {
   return (x > std::numeric_limits<int32_t>::min() &&
           x < std::numeric_limits<int32_t>::max())
-           ? (int32_t)x
+           ? static_cast<int32_t>(x)
            : (std::signbit(x) ? std::numeric_limits<int32_t>::min()
                               : std::numeric_limits<int32_t>::max());
 }
@@ -61,15 +61,16 @@
 
 uint64_t wasm::toUInteger64(double x) {
   return std::signbit(x) ? 0
-                         : (x < (double)std::numeric_limits<uint64_t>::max()
-                              ? (uint64_t)x
+                         : (x < static_cast<double>(std::numeric_limits<uint64_t>::max())
+                              ? static_cast<uint64_t>(x)
                               : std::numeric_limits<uint64_t>::max());
 }
 
 int64_t wasm::toSInteger64(double x) {
-  return (x > (double)std::numeric_limits<int64_t>::min() &&
-          x < (double)std::numeric_limits<int64_t>::max())
-           ? (int64_t)x
+  return (x > static_cast<double>(std::numeric_limits<int64_t>::min()) &&
+          x < static_cast<double>(std::numeric_limits<int64_t>::max()))
+
+           ? static_cast<int64_t>(x)
            : (std::signbit(x) ? std::numeric_limits<int64_t>::min()
                               : std::numeric_limits<int64_t>::max());
 }
diff --git a/src/support/string.cpp b/src/support/string.cpp
index bdb54f1..e395275 100644
--- a/src/support/string.cpp
+++ b/src/support/string.cpp
@@ -267,7 +267,7 @@
   }
 
   // Use a little-endian encoding.
-  uint16_t u = uint8_t(str[0]) | (uint8_t(str[1]) << 8);
+  uint16_t u = static_cast<uint8_t>(str[0]) | (static_cast<uint8_t>(str[1]) << 8);
   str = str.substr(2);
   return u;
 }
@@ -302,8 +302,8 @@
 
 void writeWTF16CodeUnit(std::ostream& os, uint16_t u) {
   // Little-endian encoding.
-  os << uint8_t(u & 0xFF);
-  os << uint8_t(u >> 8);
+  os << static_cast<uint8_t>(u & 0xFF);
+  os << static_cast<uint8_t>(u >> 8);
 }
 
 constexpr uint32_t replacementCharacter = 0xFFFD;
@@ -331,22 +331,22 @@
   assert(u < 0x110000);
   if (u < 0x80) {
     // 0xxxxxxx
-    os << uint8_t(u);
+    os << static_cast<uint8_t>(u);
   } else if (u < 0x800) {
     // 110xxxxx 10xxxxxx
-    os << uint8_t(0b11000000 | ((u >> 6) & 0b00011111));
-    os << uint8_t(0b10000000 | ((u >> 0) & 0b00111111));
+    os << static_cast<uint8_t>(0b11000000 | ((u >> 6) & 0b00011111));
+    os << static_cast<uint8_t>(0b10000000 | ((u >> 0) & 0b00111111));
   } else if (u < 0x10000) {
     // 1110xxxx 10xxxxxx 10xxxxxx
-    os << uint8_t(0b11100000 | ((u >> 12) & 0b00001111));
-    os << uint8_t(0b10000000 | ((u >> 6) & 0b00111111));
-    os << uint8_t(0b10000000 | ((u >> 0) & 0b00111111));
+    os << static_cast<uint8_t>(0b11100000 | ((u >> 12) & 0b00001111));
+    os << static_cast<uint8_t>(0b10000000 | ((u >> 6) & 0b00111111));
+    os << static_cast<uint8_t>(0b10000000 | ((u >> 0) & 0b00111111));
   } else {
     // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-    os << uint8_t(0b11110000 | ((u >> 18) & 0b00000111));
-    os << uint8_t(0b10000000 | ((u >> 12) & 0b00111111));
-    os << uint8_t(0b10000000 | ((u >> 6) & 0b00111111));
-    os << uint8_t(0b10000000 | ((u >> 0) & 0b00111111));
+    os << static_cast<uint8_t>(0b11110000 | ((u >> 18) & 0b00000111));
+    os << static_cast<uint8_t>(0b10000000 | ((u >> 12) & 0b00111111));
+    os << static_cast<uint8_t>(0b10000000 | ((u >> 6) & 0b00111111));
+    os << static_cast<uint8_t>(0b10000000 | ((u >> 0) & 0b00111111));
   }
   return os;
 }
@@ -442,7 +442,7 @@
     bool isNaivelyPrintable = 32 <= u && u < 127;
     if (isNaivelyPrintable) {
       assert(u < 0x80 && "need additional logic to emit valid UTF-8");
-      os << uint8_t(u);
+      os << static_cast<uint8_t>(u);
       continue;
     }
 
diff --git a/src/support/threads.cpp b/src/support/threads.cpp
index ceb39f3..6e7a99b 100644
--- a/src/support/threads.cpp
+++ b/src/support/threads.cpp
@@ -230,7 +230,7 @@
   DEBUG_POOL("work() is done\n");
 }
 
-size_t ThreadPool::size() { return std::max(size_t(1), threads.size()); }
+size_t ThreadPool::size() { return std::max(static_cast<size_t>(1), threads.size()); }
 
 bool ThreadPool::isRunning() {
   DEBUG_POOL("check if running\n");
diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h
index f3b45c0..6e43758 100644
--- a/src/tools/execution-results.h
+++ b/src/tools/execution-results.h
@@ -166,9 +166,9 @@
               // To avoid JS legalization changing logging results, treat a
               // logging of an i64 as two i32s (which is what legalization
               // would turn us into).
-              auto low = Literal(int32_t(argument.getInteger()));
+              auto low = Literal(static_cast<int32_t>(argument.getInteger()));
               auto high =
-                Literal(int32_t(argument.getInteger() >> int32_t(32)));
+                Literal(static_cast<int32_t>(argument.getInteger() >> static_cast<int32_t>(32)));
               std::cout << ' ' << low;
               loggings.push_back(low);
               std::cout << ' ' << high;
@@ -227,9 +227,9 @@
         } else if (import->base == "call-export-catch") {
           try {
             callExportAsJS(arguments[0].geti32());
-            return {Literal(int32_t(0))};
+            return {Literal(static_cast<int32_t>(0))};
           } catch (const WasmException& e) {
-            return {Literal(int32_t(1))};
+            return {Literal(static_cast<int32_t>(1))};
           }
         } else if (import->base == "call-ref") {
           // Similar to call-export*, but with a ref.
@@ -238,9 +238,9 @@
         } else if (import->base == "call-ref-catch") {
           try {
             callRefAsJS(arguments[0]);
-            return {Literal(int32_t(0))};
+            return {Literal(static_cast<int32_t>(0))};
           } catch (const WasmException& e) {
-            return {Literal(int32_t(1))};
+            return {Literal(static_cast<int32_t>(1))};
           }
         } else if (import->base == "sleep") {
           // Do not actually sleep, just return the id.
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index fc3a4f5..6521ea7 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -997,7 +997,7 @@
   auto glob =
     builder.makeGlobal(HANG_LIMIT_GLOBAL,
                        Type::i32,
-                       builder.makeConst(int32_t(fuzzParams->HANG_LIMIT)),
+                       builder.makeConst(static_cast<int32_t>(fuzzParams->HANG_LIMIT)),
                        Builder::Mutable);
   wasm.addGlobal(std::move(glob));
 }
@@ -1214,7 +1214,7 @@
   // }
   std::vector<Expression*> contents;
   contents.push_back(
-    builder.makeLocalSet(0, builder.makeConst(uint32_t(5381))));
+    builder.makeLocalSet(0, builder.makeConst(static_cast<uint32_t>(5381))));
   auto zero = Literal::makeFromInt32(0, wasm.memories[0]->addressType);
   for (Index i = 0; i < fuzzParams->USABLE_MEMORY; i++) {
     contents.push_back(builder.makeLocalSet(
@@ -1225,7 +1225,7 @@
           AddInt32,
           builder.makeBinary(ShlInt32,
                              builder.makeLocalGet(0, Type::i32),
-                             builder.makeConst(uint32_t(5))),
+                             builder.makeConst(static_cast<uint32_t>(5))),
           builder.makeLocalGet(0, Type::i32)),
         builder.makeLoad(1,
                          false,
@@ -1399,14 +1399,14 @@
       builder.makeUnary(UnaryOp::EqZInt32,
                         builder.makeGlobalGet(HANG_LIMIT_GLOBAL, Type::i32)),
       builder.makeSequence(builder.makeGlobalSet(HANG_LIMIT_GLOBAL,
-                                                 builder.makeConst(int32_t(
+                                                 builder.makeConst(static_cast<int32_t>(
                                                    fuzzParams->HANG_LIMIT))),
                            builder.makeUnreachable())),
     builder.makeGlobalSet(
       HANG_LIMIT_GLOBAL,
       builder.makeBinary(BinaryOp::SubInt32,
                          builder.makeGlobalGet(HANG_LIMIT_GLOBAL, Type::i32),
-                         builder.makeConst(int32_t(1)))));
+                         builder.makeConst(static_cast<int32_t>(1)))));
 }
 
 Expression* TranslateToFuzzReader::makeImportLogging() {
@@ -1425,7 +1425,7 @@
   // a wasm tag. Emit 0 or non-zero with ~equal probability.
   Expression* arg;
   if (oneIn(2)) {
-    arg = builder.makeConst(int32_t(0));
+    arg = builder.makeConst(static_cast<int32_t>(0));
   } else {
     arg = makeConst(Type::i32);
   }
@@ -1501,7 +1501,7 @@
   auto* index = make(Type::i32);
   if (!allowOOB || !oneIn(10)) {
     index = builder.makeBinary(
-      RemUInt32, index, builder.makeConst(int32_t(maxIndex)));
+      RemUInt32, index, builder.makeConst(static_cast<int32_t>(maxIndex)));
   }
 
   // The non-catching variants send a flags argument, which says whether to
@@ -1668,7 +1668,7 @@
   auto& funcTypes = interestingHeapSubTypes[HeapTypes::func];
   if (!funcTypes.empty() && oneIn(2)) {
     auto type = pick(funcTypes);
-    if (type.getSignature().params.size() < (size_t)fuzzParams->MAX_PARAMS) {
+    if (type.getSignature().params.size() < static_cast<size_t>(fuzzParams->MAX_PARAMS)) {
       // This is suitable for us.
       funcType = type;
     }
@@ -1795,7 +1795,7 @@
   for (auto* arrayNew : FindAll<ArrayNew>(func->body).list) {
     if (!oneIn(100)) {
       arrayNew->size = builder.makeBinary(
-        AndInt32, arrayNew->size, builder.makeConst(int32_t(1024 - 1)));
+        AndInt32, arrayNew->size, builder.makeConst(static_cast<int32_t>(1024 - 1)));
     }
   }
 }
@@ -3253,12 +3253,12 @@
       ret = builder.makeBinary(
         AndInt64,
         ret,
-        builder.makeConst(int64_t(fuzzParams->USABLE_MEMORY - 1)));
+        builder.makeConst(static_cast<int64_t>(fuzzParams->USABLE_MEMORY - 1)));
     } else {
       ret = builder.makeBinary(
         AndInt32,
         ret,
-        builder.makeConst(int32_t(fuzzParams->USABLE_MEMORY - 1)));
+        builder.makeConst(static_cast<int32_t>(fuzzParams->USABLE_MEMORY - 1)));
     }
   }
   return ret;
@@ -3594,35 +3594,35 @@
       int64_t small;
       switch (upTo(6)) {
         case 0:
-          small = int8_t(get());
+          small = static_cast<int8_t>(get());
           break;
         case 1:
-          small = uint8_t(get());
+          small = static_cast<uint8_t>(get());
           break;
         case 2:
-          small = int16_t(get16());
+          small = static_cast<int16_t>(get16());
           break;
         case 3:
-          small = uint16_t(get16());
+          small = static_cast<uint16_t>(get16());
           break;
         case 4:
-          small = int32_t(get32());
+          small = static_cast<int32_t>(get32());
           break;
         case 5:
-          small = uint32_t(get32());
+          small = static_cast<uint32_t>(get32());
           break;
         default:
           WASM_UNREACHABLE("invalid value");
       }
       switch (type.getBasic()) {
         case Type::i32:
-          return Literal(int32_t(small));
+          return Literal(static_cast<int32_t>(small));
         case Type::i64:
-          return Literal(int64_t(small));
+          return Literal(static_cast<int64_t>(small));
         case Type::f32:
-          return Literal(float(small));
+          return Literal(static_cast<float>(small));
         case Type::f64:
-          return Literal(double(small));
+          return Literal(static_cast<double>(small));
         case Type::v128:
         case Type::none:
         case Type::unreachable:
@@ -3699,16 +3699,16 @@
       Literal value;
       switch (type.getBasic()) {
         case Type::i32:
-          value = Literal(int32_t(1) << upTo(32));
+          value = Literal(static_cast<int32_t>(1) << upTo(32));
           break;
         case Type::i64:
-          value = Literal(int64_t(1) << upTo(64));
+          value = Literal(static_cast<int64_t>(1) << upTo(64));
           break;
         case Type::f32:
-          value = Literal(float(int64_t(1) << upTo(64)));
+          value = Literal(static_cast<float>(static_cast<int64_t>(1) << upTo(64)));
           break;
         case Type::f64:
-          value = Literal(double(int64_t(1) << upTo(64)));
+          value = Literal(static_cast<double>(static_cast<int64_t>(1) << upTo(64)));
           break;
         case Type::v128:
         case Type::none:
@@ -3778,8 +3778,8 @@
     heapType = (*builder.build())[0];
   }
   auto* body = heapType.getSignature().results == Type::none
-                 ? (Expression*)builder.makeNop()
-                 : (Expression*)builder.makeUnreachable();
+                 ? static_cast<Expression*>(builder.makeNop())
+                 : static_cast<Expression*>(builder.makeUnreachable());
   auto* func = wasm.addFunction(
     builder.makeFunction(Names::getValidFunctionName(wasm, "ref_func_target"),
                          Type(heapType, NonNullable, Exact),
@@ -4111,7 +4111,7 @@
         init = makeChild(element.type);
       }
       auto* count =
-        builder.makeConst(int32_t(upTo(fuzzParams->MAX_ARRAY_SIZE)));
+        builder.makeConst(static_cast<int32_t>(upTo(fuzzParams->MAX_ARRAY_SIZE)));
       return builder.makeArrayNew(type.getHeapType(), count, init);
     }
     case HeapTypeKind::Cont: {
@@ -5738,8 +5738,8 @@
   size_t offsetVal = upTo(totalSize);
   size_t sizeVal = upTo(totalSize - offsetVal);
   Expression* dest = makePointer();
-  Expression* offset = builder.makeConst(int32_t(offsetVal));
-  Expression* size = builder.makeConst(int32_t(sizeVal));
+  Expression* offset = builder.makeConst(static_cast<int32_t>(offsetVal));
+  Expression* size = builder.makeConst(static_cast<int32_t>(sizeVal));
   return builder.makeMemoryInit(
     segment, dest, offset, size, wasm.memories[0]->name);
 }
diff --git a/src/tools/fuzzing/random.cpp b/src/tools/fuzzing/random.cpp
index cfcdbdd..84dbcf5 100644
--- a/src/tools/fuzzing/random.cpp
+++ b/src/tools/fuzzing/random.cpp
@@ -47,18 +47,18 @@
 }
 
 int16_t Random::get16() {
-  auto temp = uint16_t(get()) << 8;
-  return temp | uint16_t(get());
+  auto temp = static_cast<uint16_t>(get()) << 8;
+  return temp | static_cast<uint16_t>(get());
 }
 
 int32_t Random::get32() {
-  auto temp = uint32_t(get16()) << 16;
-  return temp | uint32_t(get16());
+  auto temp = static_cast<uint32_t>(get16()) << 16;
+  return temp | static_cast<uint32_t>(get16());
 }
 
 int64_t Random::get64() {
-  auto temp = uint64_t(get32()) << 32;
-  return temp | uint64_t(get32());
+  auto temp = static_cast<uint64_t>(get32()) << 32;
+  return temp | static_cast<uint64_t>(get32());
 }
 
 float Random::getFloat() { return Literal(get32()).reinterpretf32(); }
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp
index 9b2800a..ac8495c 100644
--- a/src/tools/wasm-ctor-eval.cpp
+++ b/src/tools/wasm-ctor-eval.cpp
@@ -347,7 +347,7 @@
             // Write out a count of i32(0) and return __WASI_ERRNO_SUCCESS
             // (0).
             store32(arguments[0].geti32(), 0, wasm->memories[0]->name);
-            return {Literal(int32_t(0))};
+            return {Literal(static_cast<int32_t>(0))};
           }
 
           if (import->base == "environ_get") {
@@ -357,7 +357,7 @@
             }
 
             // Just return __WASI_ERRNO_SUCCESS (0).
-            return {Literal(int32_t(0))};
+            return {Literal(static_cast<int32_t>(0))};
           }
 
           if (import->base == "args_sizes_get") {
@@ -369,7 +369,7 @@
             // Write out an argc of i32(0) and return a __WASI_ERRNO_SUCCESS
             // (0).
             store32(arguments[0].geti32(), 0, wasm->memories[0]->name);
-            return {Literal(int32_t(0))};
+            return {Literal(static_cast<int32_t>(0))};
           }
 
           if (import->base == "args_get") {
@@ -379,7 +379,7 @@
             }
 
             // Just return __WASI_ERRNO_SUCCESS (0).
-            return {Literal(int32_t(0))};
+            return {Literal(static_cast<int32_t>(0))};
           }
 
           // Otherwise, we don't recognize this import; continue normally to
@@ -1006,7 +1006,7 @@
         builder.makeStructSet(index, getGlobal, value, MemoryOrder::Unordered);
     } else {
       set = builder.makeArraySet(getGlobal,
-                                 builder.makeConst(int32_t(index)),
+                                 builder.makeConst(static_cast<int32_t>(index)),
                                  value,
                                  MemoryOrder::Unordered);
     }
diff --git a/src/tools/wasm-fuzz-lattices.cpp b/src/tools/wasm-fuzz-lattices.cpp
index a6231cd..3adc0cd 100644
--- a/src/tools/wasm-fuzz-lattices.cpp
+++ b/src/tools/wasm-fuzz-lattices.cpp
@@ -995,7 +995,7 @@
     // Fewer bytes are needed to generate three random lattices.
     std::vector<char> funcBytes(128);
     for (size_t i = 0; i < funcBytes.size(); i += sizeof(uint64_t)) {
-      *(uint64_t*)(funcBytes.data() + i) = getFuncRand();
+      *reinterpret_cast<uint64_t*>(funcBytes.data() + i) = getFuncRand();
     }
 
     Random rand(std::move(funcBytes));
@@ -1030,7 +1030,7 @@
     // 4kb of random bytes should be enough for anyone!
     std::vector<char> bytes(4096);
     for (size_t i = 0; i < bytes.size(); i += sizeof(uint64_t)) {
-      *(uint64_t*)(bytes.data() + i) = getRand();
+      *reinterpret_cast<uint64_t*>(bytes.data() + i) = getRand();
     }
 
     Module testModule;
@@ -1075,7 +1075,7 @@
               WasmFuzzTypesOption,
               Options::Arguments::One,
               [&](Options*, const std::string& arg) {
-                seed = uint64_t(std::stoull(arg));
+                seed = static_cast<uint64_t>(std::stoull(arg));
               });
 
   std::optional<uint64_t> latticeElementSeed;
@@ -1085,7 +1085,7 @@
               WasmFuzzTypesOption,
               Options::Arguments::One,
               [&](Options*, const std::string& arg) {
-                latticeElementSeed = uint64_t(std::stoull(arg));
+                latticeElementSeed = static_cast<uint64_t>(std::stoull(arg));
               });
 
   std::optional<std::string> functionName;
diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp
index dc04ae9..d21020d 100644
--- a/src/tools/wasm-fuzz-types.cpp
+++ b/src/tools/wasm-fuzz-types.cpp
@@ -68,7 +68,7 @@
   // 4kb of random bytes should be enough for anyone!
   std::vector<char> bytes(4096);
   for (size_t i = 0; i < bytes.size(); i += sizeof(uint64_t)) {
-    *(uint64_t*)(bytes.data() + i) = getRand();
+    *reinterpret_cast<uint64_t*>(bytes.data() + i) = getRand();
   }
   rand = Random(std::move(bytes));
 
@@ -640,7 +640,7 @@
               WasmFuzzTypesOption,
               Options::Arguments::One,
               [&](Options*, const std::string& arg) {
-                seed = uint64_t(std::stoull(arg));
+                seed = static_cast<uint64_t>(std::stoull(arg));
               });
 
   bool verbose = false;
diff --git a/src/tools/wasm-reduce/wasm-reduce.cpp b/src/tools/wasm-reduce/wasm-reduce.cpp
index 03249ba..8b7fc76 100644
--- a/src/tools/wasm-reduce/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce/wasm-reduce.cpp
@@ -150,7 +150,7 @@
     if (!GetExitCodeProcess(pi.hProcess, &dwordExitCode)) {
       Fatal() << "GetExitCodeProcess failed: " << GetLastErrorStdStr() << ".\n";
     }
-    code = (int)dwordExitCode;
+    code = static_cast<int>(dwordExitCode);
 
     // Close process and thread handles.
     CloseHandle(pi.hProcess);
@@ -838,7 +838,7 @@
           std::cerr << "|      shrank segment from " << save.size() << " => "
                     << data.size() << " (skip: " << skip << ")\n";
           noteReduction();
-          skip = std::min(size_t(factor), 2 * skip);
+          skip = std::min(static_cast<size_t>(factor), 2 * skip);
         } else {
           data = std::move(save);
           return false;
@@ -946,10 +946,10 @@
         // Subtract 1 since the loop increments us anyhow by one: we want to
         // skip over the skipped functions, and not any more.
         x += skip - 1;
-        skip = std::min(size_t(factor), 2 * skip);
+        skip = std::min(static_cast<size_t>(factor), 2 * skip);
         maxSkip = std::max(skip, maxSkip);
       } else {
-        skip = std::max(skip / 2, size_t(1)); // or 1?
+        skip = std::max(skip / 2, static_cast<size_t>(1)); // or 1?
         x += factor / 100;
       }
     }
@@ -1000,12 +1000,12 @@
         for (auto exp : currExports) {
           module->addExport(new Export(exp));
         }
-        skip = std::max(skip / 2, size_t(1)); // or 1?
+        skip = std::max(skip / 2, static_cast<size_t>(1)); // or 1?
       } else {
         std::cerr << "|      removed " << currExports.size() << " exports\n";
         noteReduction(currExports.size());
         i += skip;
-        skip = std::min(size_t(factor), 2 * skip);
+        skip = std::min(static_cast<size_t>(factor), 2 * skip);
       }
     }
     // If we are left with a single function that is not exported or used in
@@ -1147,9 +1147,9 @@
     if (condition->is<Const>()) {
       return;
     }
-    auto* c = builder->makeConst(int32_t(0));
+    auto* c = builder->makeConst(static_cast<int32_t>(0));
     if (!tryToReplaceChild(condition, c)) {
-      c->value = Literal(int32_t(1));
+      c->value = Literal(static_cast<int32_t>(1));
       tryToReplaceChild(condition, c);
     }
   }
@@ -1561,7 +1561,7 @@
 
     // no point in a factor lorger than the size
     assert(newSize > 4); // wasm modules are >4 bytes anyhow
-    factor = std::min(factor, int(newSize) / 4);
+    factor = std::min(factor, static_cast<int>(newSize) / 4);
 
     // try to reduce destructively. if a high factor fails to find anything,
     // quickly try a lower one (no point in doing passes until we reduce
diff --git a/src/tools/wasm-split/instrumenter.cpp b/src/tools/wasm-split/instrumenter.cpp
index 56fa673..be46a34 100644
--- a/src/tools/wasm-split/instrumenter.cpp
+++ b/src/tools/wasm-split/instrumenter.cpp
@@ -152,7 +152,7 @@
           builder.makeAtomicStore(1,
                                   funcIdx,
                                   builder.makeConstPtr(0, Type::i32),
-                                  builder.makeConst(uint32_t(1)),
+                                  builder.makeConst(static_cast<uint32_t>(1)),
                                   Type::i32,
                                   memoryName,
                                   MemoryOrder::SeqCst),
@@ -221,9 +221,9 @@
   Builder builder(*wasm);
   auto getAddr = [&]() { return builder.makeLocalGet(0, ptrType); };
   auto getSize = [&]() { return builder.makeLocalGet(1, Type::i32); };
-  auto hashConst = [&]() { return builder.makeConst(int64_t(moduleHash)); };
+  auto hashConst = [&]() { return builder.makeConst(static_cast<int64_t>(moduleHash)); };
   auto profileSizeConst = [&]() {
-    return builder.makeConst(int32_t(profileSize));
+    return builder.makeConst(static_cast<int32_t>(profileSize));
   };
 
   // Write the hash followed by all the time stamps
@@ -286,7 +286,7 @@
                 nullptr,
                 builder.makeBinary(EqInt32,
                                    getFuncIdx(),
-                                   builder.makeConst(uint32_t(numFuncs)))),
+                                   builder.makeConst(static_cast<uint32_t>(numFuncs)))),
               builder.makeStore(
                 4,
                 offset,
@@ -295,7 +295,7 @@
                   AddInt32,
                   getAddr(),
                   builder.makeBinary(
-                    MulInt32, getFuncIdx(), builder.makeConst(uint32_t(4)))),
+                    MulInt32, getFuncIdx(), builder.makeConst(static_cast<uint32_t>(4)))),
                 builder.makeAtomicLoad(1,
                                        0,
                                        getFuncIdx(),
@@ -307,7 +307,7 @@
               builder.makeLocalSet(
                 funcIdxVar,
                 builder.makeBinary(
-                  AddInt32, getFuncIdx(), builder.makeConst(uint32_t(1)))),
+                  AddInt32, getFuncIdx(), builder.makeConst(static_cast<uint32_t>(1)))),
               builder.makeBreak("l")))));
       break;
     }
diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp
index ccb63b8..cd33d5f 100644
--- a/src/tools/wasm-split/wasm-split.cpp
+++ b/src/tools/wasm-split/wasm-split.cpp
@@ -64,7 +64,7 @@
   for (char c : contents) {
     hash_combine(digest, c);
   }
-  return uint64_t(digest);
+  return static_cast<uint64_t>(digest);
 }
 
 void adjustTableSize(Module& wasm, int initialSize, bool secondary = false) {
@@ -81,11 +81,11 @@
 
   auto& table = wasm.tables.front();
 
-  if ((uint64_t)initialSize < table->initial) {
+  if (static_cast<uint64_t>(initialSize) < table->initial) {
     Fatal() << "Specified initial table size too small, should be at least "
             << table->initial;
   }
-  if ((uint64_t)initialSize > table->max) {
+  if (static_cast<uint64_t>(initialSize) > table->max) {
     Fatal() << "Specified initial table size larger than max table size "
             << table->max;
   }
@@ -153,15 +153,15 @@
       Fatal() << "Unexpected end of profile data in " << file;
     }
     uint32_t i32 = 0;
-    i32 |= uint32_t(uint8_t(profileData[i++]));
-    i32 |= uint32_t(uint8_t(profileData[i++])) << 8;
-    i32 |= uint32_t(uint8_t(profileData[i++])) << 16;
-    i32 |= uint32_t(uint8_t(profileData[i++])) << 24;
+    i32 |= static_cast<uint32_t>(static_cast<uint8_t>(profileData[i++]));
+    i32 |= static_cast<uint32_t>(static_cast<uint8_t>(profileData[i++])) << 8;
+    i32 |= static_cast<uint32_t>(static_cast<uint8_t>(profileData[i++])) << 16;
+    i32 |= static_cast<uint32_t>(static_cast<uint8_t>(profileData[i++])) << 24;
     return i32;
   };
 
   uint64_t hash = readi32();
-  hash |= uint64_t(readi32()) << 32;
+  hash |= static_cast<uint64_t>(readi32()) << 32;
 
   std::vector<size_t> timestamps;
   while (i < profileData.size()) {
@@ -547,7 +547,7 @@
   BufferWithRandomAccess buffer;
   buffer << data.hash;
   for (size_t t = 0; t < data.timestamps.size(); ++t) {
-    buffer << uint32_t(data.timestamps[t]);
+    buffer << static_cast<uint32_t>(data.timestamps[t]);
   }
   Output out(options.output, Flags::Binary);
   buffer.writeTo(out.getStream());
@@ -560,7 +560,7 @@
         isxdigit(input[i + 1]) && isxdigit(input[i + 2])) {
       std::string byte = input.substr(i + 1, 2);
       i += 2;
-      char chr = (char)(int)strtol(byte.c_str(), nullptr, 16);
+      char chr = static_cast<char>(strtol(byte.c_str(), nullptr, 16));
       output.push_back(chr);
     } else {
       output.push_back(input[i]);
diff --git a/src/tools/wasm2c-wrapper.h b/src/tools/wasm2c-wrapper.h
index 38c924b..61ba90c 100644
--- a/src/tools/wasm2c-wrapper.h
+++ b/src/tools/wasm2c-wrapper.h
@@ -38,7 +38,7 @@
       // This must be escaped, as prefix + hex character code.
       mangled += escapePrefix;
       std::stringstream ss;
-      ss << std::hex << std::uppercase << unsigned(c);
+      ss << std::hex << std::uppercase << static_cast<unsigned>(c);
       mangled += ss.str();
     }
   }
@@ -61,6 +61,7 @@
         return 'd';
       default:
         Fatal() << "unhandled wasm2c wrapper signature type: " << type;
+        WASM_UNREACHABLE("unhandled type");
     }
   };
 
@@ -93,7 +94,7 @@
 void (*Z_fuzzingZ2DsupportZ_logZ2Di32Z_vi)(u32) = _Z_fuzzingZ2DsupportZ_logZ2Di32Z_vi;
 
 void _Z_fuzzingZ2DsupportZ_logZ2Di64Z_vj(u64 x) {
-  printf("[LoggingExternalInterface logging %" PRId64 "]\n", (int64_t)x);
+  printf("[LoggingExternalInterface logging %" PRId64 "]\n", static_cast<int64_t>(x));
 }
 void (*Z_fuzzingZ2DsupportZ_logZ2Di64Z_vj)(u64) = _Z_fuzzingZ2DsupportZ_logZ2Di64Z_vj;
 
diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp
index 4821070..4576a76 100644
--- a/src/tools/wasm2js.cpp
+++ b/src/tools/wasm2js.cpp
@@ -364,9 +364,9 @@
         } else if (node[1] == LSHIFT) {
           node->setNumber(left << (right & 31));
         } else if (node[1] == RSHIFT) {
-          node->setNumber(int32_t(left) >> int32_t(right & 31));
+          node->setNumber(static_cast<int32_t>(left) >> static_cast<int32_t>(right & 31));
         } else if (node[1] == TRSHIFT) {
-          node->setNumber(uint32_t(left) >> uint32_t(right & 31));
+          node->setNumber(static_cast<uint32_t>(left) >> static_cast<uint32_t>(right & 31));
         }
         return;
       }
@@ -615,7 +615,7 @@
   Builder builder(wasm);
   if (assn.expected.empty()) {
     if (actual->type == Type::none) {
-      body = builder.blockify(actual, builder.makeConst(uint32_t(1)));
+      body = builder.blockify(actual, builder.makeConst(static_cast<uint32_t>(1)));
     } else {
       body = actual;
     }
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index f12db25..1c09fad 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -123,15 +123,15 @@
         break;
       }
       shift += 7;
-      if (size_t(shift) >= sizeof(T) * 8) {
+      if (static_cast<size_t>(shift) >= sizeof(T) * 8) {
         throw ParseException("LEB overflow");
       }
     }
     // If signed LEB, then we might need to sign-extend.
     if constexpr (std::is_signed_v<T>) {
       shift += 7;
-      if ((byte & 64) && size_t(shift) < 8 * sizeof(T)) {
-        size_t sext_bits = 8 * sizeof(T) - size_t(shift);
+      if ((byte & 64) && static_cast<size_t>(shift) < 8 * sizeof(T)) {
+        size_t sext_bits = 8 * sizeof(T) - static_cast<size_t>(shift);
         value <<= sext_bits;
         value >>= sext_bits;
         if (value >= 0) {
@@ -212,10 +212,10 @@
     return *this;
   }
 
-  BufferWithRandomAccess& operator<<(uint8_t x) { return *this << (int8_t)x; }
-  BufferWithRandomAccess& operator<<(uint16_t x) { return *this << (int16_t)x; }
-  BufferWithRandomAccess& operator<<(uint32_t x) { return *this << (int32_t)x; }
-  BufferWithRandomAccess& operator<<(uint64_t x) { return *this << (int64_t)x; }
+  BufferWithRandomAccess& operator<<(uint8_t x) { return *this << static_cast<int8_t>(x); }
+  BufferWithRandomAccess& operator<<(uint16_t x) { return *this << static_cast<int16_t>(x); }
+  BufferWithRandomAccess& operator<<(uint32_t x) { return *this << static_cast<int32_t>(x); }
+  BufferWithRandomAccess& operator<<(uint64_t x) { return *this << static_cast<int64_t>(x); }
 
   BufferWithRandomAccess& operator<<(float x) {
     return *this << Literal(x).reinterpreti32();
@@ -266,8 +266,8 @@
   // later, when the size is known.
   BinaryLocation writeU32LEBPlaceholder() {
     BinaryLocation ret = size();
-    *this << int32_t(0);
-    *this << int8_t(0);
+    *this << static_cast<int32_t>(0);
+    *this << static_cast<int8_t>(0);
     return ret;
   }
 
@@ -303,7 +303,7 @@
     auto data = name.data();
     *this << U32LEB(size);
     for (size_t i = 0; i < size; i++) {
-      *this << int8_t(data[i]);
+      *this << static_cast<int8_t>(data[i]);
     }
   }
 };
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 1740e36..17aef24 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -1422,8 +1422,8 @@
       for (auto c : value.getGCData()->values) {
         auto u = c.getInteger();
         assert(u < 0x10000);
-        wtf16 << uint8_t(u & 0xFF);
-        wtf16 << uint8_t(u >> 8);
+        wtf16 << static_cast<uint8_t>(u & 0xFF);
+        wtf16 << static_cast<uint8_t>(u >> 8);
       }
       // TODO: Use wtf16.view() once we have C++20.
       return makeStringConst(wtf16.str());
@@ -1582,16 +1582,16 @@
     // TODO: reuse node conditionally when possible for literals
     switch (curr->type.getBasic()) {
       case Type::i32:
-        value = Literal(int32_t(0));
+        value = Literal(static_cast<int32_t>(0));
         break;
       case Type::i64:
-        value = Literal(int64_t(0));
+        value = Literal(static_cast<int64_t>(0));
         break;
       case Type::f32:
-        value = Literal(float(0));
+        value = Literal(static_cast<float>(0));
         break;
       case Type::f64:
-        value = Literal(double(0));
+        value = Literal(static_cast<double>(0));
         break;
       case Type::v128: {
         std::array<uint8_t, 16> bytes;
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index b028163..3135852 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -659,7 +659,7 @@
               pushResumeEntry(values.back(), "child value");
               values.pop_back();
             }
-            pushResumeEntry({Literal(int32_t(num))}, "num executed children");
+            pushResumeEntry({Literal(static_cast<int32_t>(num))}, "num executed children");
           }
         }
       }
@@ -722,8 +722,8 @@
       // To return to the same place when we resume, we add an entry with two
       // pieces of information: the index in the stack of blocks, and the index
       // in the block.
-      entry.push_back(Literal(uint32_t(stack.size())));
-      entry.push_back(Literal(uint32_t(blockIndex)));
+      entry.push_back(Literal(static_cast<uint32_t>(stack.size())));
+      entry.push_back(Literal(static_cast<uint32_t>(blockIndex)));
       pushResumeEntry(entry, "block");
     };
     Index blockIndex = 0;
@@ -773,7 +773,7 @@
       //   0 - suspended in the condition
       //   1 - suspended in the ifTrue arm
       //   2 - suspended in the ifFalse arm
-      pushResumeEntry({Literal(int32_t(resumeIndex))}, "if");
+      pushResumeEntry({Literal(static_cast<int32_t>(resumeIndex))}, "if");
     };
     Index resumeIndex = -1;
     if (isResuming()) {
@@ -862,8 +862,8 @@
     VISIT_REUSE(flow, curr->condition);
     int64_t index = flow.getSingleValue().getInteger();
     Name target = curr->default_;
-    if (index >= 0 && (size_t)index < curr->targets.size()) {
-      target = curr->targets[(size_t)index];
+    if (index >= 0 && static_cast<size_t>(index) < curr->targets.size()) {
+      target = curr->targets[static_cast<size_t>(index)];
     }
     flow.breakTo = target;
     flow.values = values;
@@ -1202,7 +1202,7 @@
         }
         if (left.getInteger() == std::numeric_limits<int32_t>::min() &&
             right.getInteger() == -1) {
-          return Literal(int32_t(0));
+          return Literal(static_cast<int32_t>(0));
         }
         return left.remS(right);
       }
@@ -1232,7 +1232,7 @@
           trap("i64.rem_s by 0");
         }
         if (left.getInteger() == LLONG_MIN && right.getInteger() == -1LL) {
-          return Literal(int64_t(0));
+          return Literal(static_cast<int64_t>(0));
         }
         return left.remS(right);
       }
@@ -1814,7 +1814,7 @@
           trap("i32.truncSFloat overflow");
         }
       }
-      return Literal(int32_t(val));
+      return Literal(static_cast<int32_t>(val));
     } else {
       if (value.type == Type::f32) {
         if (!isInRangeI64TruncS(value.reinterpreti32())) {
@@ -1825,7 +1825,7 @@
           trap("i64.truncSFloat overflow");
         }
       }
-      return Literal(int64_t(val));
+      return Literal(static_cast<int64_t>(val));
     }
   }
 
@@ -1844,7 +1844,7 @@
           trap("i32.truncUFloat overflow");
         }
       }
-      return Literal(uint32_t(val));
+      return Literal(static_cast<uint32_t>(val));
     } else {
       if (value.type == Type::f32) {
         if (!isInRangeI64TruncU(value.reinterpreti32())) {
@@ -1855,7 +1855,7 @@
           trap("i64.truncUFloat overflow");
         }
       }
-      return Literal(uint64_t(val));
+      return Literal(static_cast<uint64_t>(val));
     }
   }
   Flow visitAtomicFence(AtomicFence* curr) {
@@ -1911,7 +1911,7 @@
   Flow visitRefIsNull(RefIsNull* curr) {
     VISIT(flow, curr->value)
     const auto& value = flow.getSingleValue();
-    return Literal(int32_t(value.isNull()));
+    return Literal(static_cast<int32_t>(value.isNull()));
   }
   Flow visitRefFunc(RefFunc* curr) {
     // The type may differ from the type in the IR: An imported function may
@@ -1930,7 +1930,7 @@
     auto left = flow.getSingleValue();
     VISIT_REUSE(flow, curr->right);
     auto right = flow.getSingleValue();
-    return Literal(int32_t(left == right));
+    return Literal(static_cast<int32_t>(left == right));
   }
   Flow visitTableGet(TableGet* curr) { WASM_UNREACHABLE("unimp"); }
   Flow visitTableSet(TableSet* curr) { WASM_UNREACHABLE("unimp"); }
@@ -2060,7 +2060,7 @@
     if (auto* breaking = cast.getBreaking()) {
       return *breaking;
     } else {
-      return Literal(int32_t(bool(cast.getSuccess())));
+      return Literal(static_cast<int32_t>(bool(cast.getSuccess())));
     }
   }
   Flow visitRefCast(RefCast* curr) {
@@ -2346,7 +2346,7 @@
     if (!data) {
       trap("null ref");
     }
-    return Literal(int32_t(data->values.size()));
+    return Literal(static_cast<int32_t>(data->values.size()));
   }
   Flow visitArrayCopy(ArrayCopy* curr) {
     VISIT(destRef, curr->destRef)
@@ -2539,7 +2539,7 @@
       trap("null ref");
     }
 
-    return Literal(int32_t(data->values.size()));
+    return Literal(static_cast<int32_t>(data->values.size()));
   }
   Flow visitStringConcat(StringConcat* curr) {
     VISIT(flow, curr->left)
@@ -2596,7 +2596,7 @@
       arrayValues[startVal + i] = strValues[i];
     }
 
-    return Literal(int32_t(strData->values.size()));
+    return Literal(static_cast<int32_t>(strData->values.size()));
   }
   Flow visitStringEq(StringEq* curr) {
     VISIT(flow, curr->left)
@@ -2659,7 +2659,7 @@
   Flow visitStringTest(StringTest* curr) {
     VISIT(flow, curr->ref)
     auto value = flow.getSingleValue();
-    return Literal((uint32_t)value.isString());
+    return Literal(value.isString());
   }
   Flow visitStringWTF16Get(StringWTF16Get* curr) {
     VISIT(ref, curr->ref)
@@ -2754,12 +2754,12 @@
       case Field::i8: {
         int8_t i;
         memcpy(&i, p, sizeof(i));
-        return truncateForPacking(Literal(int32_t(i)), field);
+        return truncateForPacking(Literal(static_cast<int32_t>(i)), field);
       }
       case Field::i16: {
         int16_t i;
         memcpy(&i, p, sizeof(i));
-        return truncateForPacking(Literal(int32_t(i)), field);
+        return truncateForPacking(Literal(static_cast<int32_t>(i)), field);
       }
       case Field::WaitQueue: {
         WASM_UNREACHABLE("waitqueue not implemented");
@@ -2995,13 +2995,13 @@
         case Type::i32: {
           switch (load->bytes) {
             case 1:
-              return load->signed_ ? Literal((int32_t)load8s(addr, memory))
-                                   : Literal((int32_t)load8u(addr, memory));
+              return load->signed_ ? Literal(static_cast<int32_t>(load8s(addr, memory)))
+                                   : Literal(static_cast<int32_t>(load8u(addr, memory)));
             case 2:
-              return load->signed_ ? Literal((int32_t)load16s(addr, memory))
-                                   : Literal((int32_t)load16u(addr, memory));
+              return load->signed_ ? Literal(static_cast<int32_t>(load16s(addr, memory)))
+                                   : Literal(static_cast<int32_t>(load16u(addr, memory)));
             case 4:
-              return Literal((int32_t)load32s(addr, memory));
+              return Literal(static_cast<int32_t>(load32s(addr, memory)));
             default:
               WASM_UNREACHABLE("invalid size");
           }
@@ -3010,16 +3010,16 @@
         case Type::i64: {
           switch (load->bytes) {
             case 1:
-              return load->signed_ ? Literal((int64_t)load8s(addr, memory))
-                                   : Literal((int64_t)load8u(addr, memory));
+              return load->signed_ ? Literal(static_cast<int64_t>(load8s(addr, memory)))
+                                   : Literal(static_cast<int64_t>(load8u(addr, memory)));
             case 2:
-              return load->signed_ ? Literal((int64_t)load16s(addr, memory))
-                                   : Literal((int64_t)load16u(addr, memory));
+              return load->signed_ ? Literal(static_cast<int64_t>(load16s(addr, memory)))
+                                   : Literal(static_cast<int64_t>(load16u(addr, memory)));
             case 4:
-              return load->signed_ ? Literal((int64_t)load32s(addr, memory))
-                                   : Literal((int64_t)load32u(addr, memory));
+              return load->signed_ ? Literal(static_cast<int64_t>(load32s(addr, memory)))
+                                   : Literal(static_cast<int64_t>(load32u(addr, memory)));
             case 8:
-              return Literal((int64_t)load64s(addr, memory));
+              return Literal(static_cast<int64_t>(load64s(addr, memory)));
             default:
               WASM_UNREACHABLE("invalid size");
           }
@@ -3332,7 +3332,7 @@
 
   std::string printFunctionStack() {
     std::string ret = "/== (binaryen interpreter stack trace)\n";
-    for (int i = int(functionStack.size()) - 1; i >= 0; i--) {
+    for (int i = static_cast<int>(functionStack.size()) - 1; i >= 0; i--) {
       ret += std::string("|: ") + functionStack[i].toString() + "\n";
     }
     ret += std::string("\\==\n");
@@ -3547,12 +3547,12 @@
     }
 
     Const zero;
-    zero.value = Literal(uint32_t(0));
+    zero.value = Literal(static_cast<uint32_t>(0));
     zero.finalize();
 
     ModuleUtils::iterActiveElementSegments(wasm, [&](ElementSegment* segment) {
       Const size;
-      size.value = Literal(uint32_t(segment->data.size()));
+      size.value = Literal(static_cast<uint32_t>(segment->data.size()));
       size.finalize();
 
       TableInit init;
@@ -3956,7 +3956,7 @@
     int step = 1;
     // Reverse direction if source is below dest
     if (sourceVal < destVal) {
-      start = int64_t(sizeVal) - 1;
+      start = static_cast<int64_t>(sizeVal) - 1;
       end = -1;
       step = -1;
     }
@@ -3974,8 +3974,8 @@
     auto* segment = wasm.getElementSegment(curr->segment);
 
     Address destVal(dest.getSingleValue().getUnsigned());
-    Address offsetVal(uint32_t(offset.getSingleValue().geti32()));
-    Address sizeVal(uint32_t(size.getSingleValue().geti32()));
+    Address offsetVal(static_cast<uint32_t>(offset.getSingleValue().geti32()));
+    Address sizeVal(static_cast<uint32_t>(size.getSingleValue().geti32()));
 
     if (offsetVal + sizeVal > 0 &&
         droppedElementSegments.count(curr->segment)) {
@@ -4127,7 +4127,7 @@
                                               memorySizeBytes,
                                               MemoryOrder::SeqCst);
     if (loaded != expected.getSingleValue()) {
-      return Literal(int32_t(1)); // not equal
+      return Literal(static_cast<int32_t>(1)); // not equal
     }
     // TODO: Add threads support. For now, report a host limit here, as there
     //       are no other threads that can wake us up. Without such threads,
@@ -4137,7 +4137,7 @@
     if (timeout.getSingleValue().getInteger() != 0) {
       hostLimit("threads support");
     }
-    return Literal(int32_t(2)); // Timed out
+    return Literal(static_cast<int32_t>(2)); // Timed out
   }
   Flow visitAtomicNotify(AtomicNotify* curr) {
     VISIT(ptr, curr->ptr)
@@ -4148,7 +4148,7 @@
       curr, ptr.getSingleValue(), 4, memorySizeBytes);
     // Just check TODO actual threads support
     info.instance->checkAtomicAddress(addr, 4, memorySizeBytes);
-    return Literal(int32_t(0)); // none woken up
+    return Literal(static_cast<int32_t>(0)); // none woken up
   }
   Flow visitSIMDLoad(SIMDLoad* curr) {
     switch (curr->op) {
@@ -4212,17 +4212,17 @@
     auto loadLane = [&](Address addr) {
       switch (curr->op) {
         case Load8x8SVec128:
-          return Literal(int32_t(info.interface()->load8s(addr, info.name)));
+          return Literal(static_cast<int32_t>(info.interface()->load8s(addr, info.name)));
         case Load8x8UVec128:
-          return Literal(int32_t(info.interface()->load8u(addr, info.name)));
+          return Literal(static_cast<int32_t>(info.interface()->load8u(addr, info.name)));
         case Load16x4SVec128:
-          return Literal(int32_t(info.interface()->load16s(addr, info.name)));
+          return Literal(static_cast<int32_t>(info.interface()->load16s(addr, info.name)));
         case Load16x4UVec128:
-          return Literal(int32_t(info.interface()->load16u(addr, info.name)));
+          return Literal(static_cast<int32_t>(info.interface()->load16u(addr, info.name)));
         case Load32x2SVec128:
-          return Literal(int64_t(info.interface()->load32s(addr, info.name)));
+          return Literal(static_cast<int64_t>(info.interface()->load32s(addr, info.name)));
         case Load32x2UVec128:
-          return Literal(int64_t(info.interface()->load32u(addr, info.name)));
+          return Literal(static_cast<int64_t>(info.interface()->load32u(addr, info.name)));
         default:
           WASM_UNREACHABLE("unexpected op");
       }
@@ -4444,7 +4444,7 @@
     int step = 1;
     // Reverse direction if source is below dest
     if (sourceVal < destVal) {
-      start = int64_t(sizeVal) - 1;
+      start = static_cast<int64_t>(sizeVal) - 1;
       end = -1;
       step = -1;
     }
@@ -4561,7 +4561,7 @@
     size_t sizeVal = size.getSingleValue().getUnsigned();
 
     size_t arraySize = data->values.size();
-    if ((uint64_t)indexVal + sizeVal > arraySize) {
+    if (static_cast<uint64_t>(indexVal) + sizeVal > arraySize) {
       trap("out of bounds array access in array.init");
     }
 
@@ -4570,7 +4570,7 @@
     auto* seg = wasm.getDataSegment(curr->segment);
     auto elem = curr->ref->type.getHeapType().getArray().element;
     size_t elemSize = elem.getByteSize();
-    uint64_t readSize = (uint64_t)sizeVal * elemSize;
+    uint64_t readSize = static_cast<uint64_t>(sizeVal) * elemSize;
     if (offsetVal + readSize > seg->data.size()) {
       trap("out of bounds segment access in array.init_data");
     }
@@ -4597,14 +4597,14 @@
     size_t sizeVal = size.getSingleValue().getUnsigned();
 
     size_t arraySize = data->values.size();
-    if ((uint64_t)indexVal + sizeVal > arraySize) {
+    if (static_cast<uint64_t>(indexVal) + sizeVal > arraySize) {
       trap("out of bounds array access in array.init");
     }
 
     Module& wasm = *self()->getModule();
 
     auto* seg = wasm.getElementSegment(curr->segment);
-    auto max = (uint64_t)offsetVal + sizeVal;
+    auto max = static_cast<uint64_t>(offsetVal) + sizeVal;
     if (max > seg->data.size()) {
       trap("out of bounds segment access in array.init_elem");
     }
@@ -4956,10 +4956,10 @@
     if (value.type == Type::i32) {
       switch (bytes) {
         case 1: {
-          return value.and_(Literal(uint32_t(0xff)));
+          return value.and_(Literal(static_cast<uint32_t>(0xff)));
         }
         case 2: {
-          return value.and_(Literal(uint32_t(0xffff)));
+          return value.and_(Literal(static_cast<uint32_t>(0xffff)));
         }
         case 4: {
           break;
@@ -4971,13 +4971,13 @@
       assert(value.type == Type::i64);
       switch (bytes) {
         case 1: {
-          return value.and_(Literal(uint64_t(0xff)));
+          return value.and_(Literal(static_cast<uint64_t>(0xff)));
         }
         case 2: {
-          return value.and_(Literal(uint64_t(0xffff)));
+          return value.and_(Literal(static_cast<uint64_t>(0xffff)));
         }
         case 4: {
-          return value.and_(Literal(uint64_t(0xffffffffUL)));
+          return value.and_(Literal(static_cast<uint64_t>(0xffffffffUL)));
         }
         case 8: {
           break;
@@ -5214,7 +5214,7 @@
     }
     checkAtomicAddress(addr, bytes, memorySizeBytes);
     Const ptr;
-    ptr.value = Literal(int32_t(addr));
+    ptr.value = Literal(static_cast<int32_t>(addr));
     ptr.type = Type::i32;
     Load load;
     load.bytes = bytes;
@@ -5236,7 +5236,7 @@
                      Address memorySizeBytes) {
     checkAtomicAddress(addr, bytes, memorySizeBytes);
     Const ptr;
-    ptr.value = Literal(int32_t(addr));
+    ptr.value = Literal(static_cast<int32_t>(addr));
     ptr.type = Type::i32;
     Const value;
     value.value = toStore;
diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h
index db9d1c1..b885449 100644
--- a/src/wasm-traversal.h
+++ b/src/wasm-traversal.h
@@ -536,7 +536,7 @@
     if (curr->is<Try>()) {
       self->pushTask(SubType::doVisitTry, currp);
       auto& catchBodies = curr->cast<Try>()->catchBodies;
-      for (int i = int(catchBodies.size()) - 1; i >= 0; i--) {
+      for (int i = static_cast<int>(catchBodies.size()) - 1; i >= 0; i--) {
         self->pushTask(SubType::scan, &catchBodies[i]);
       }
       self->pushTask(SubType::doLeaveTry, currp);
diff --git a/src/wasm-type.h b/src/wasm-type.h
index 8361c90..163f842 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -301,7 +301,7 @@
   // nullable and bit 2 set iff the reference type is exact.
   //
   // Since `Type` is really just a single integer, it should be passed by value.
-  // This is a uintptr_t rather than a TypeID (uint64_t) to save memory on
+  // This is a uintptr_t rather than a TypeID static_cast<uint64_t>(to) save memory on
   // 32-bit platforms.
   uintptr_t id;
 
@@ -393,7 +393,7 @@
   bool isTuple() const { return !isBasic() && (id & TupleMask); }
   const Tuple& getTuple() const {
     assert(isTuple());
-    return *(Tuple*)(id & ~TupleMask);
+    return *reinterpret_cast<Tuple*>(id & ~TupleMask);
   }
 
   bool isRef() const { return !isBasic() && !(id & TupleMask); }
@@ -570,7 +570,7 @@
   std::string toString() const;
 
   size_t size() const {
-    return isTuple() ? getTuple().size() : size_t(id != Type::none);
+    return isTuple() ? getTuple().size() : static_cast<size_t>(id != Type::none);
   }
 
   struct Iterator : ParentIndexIterator<const Type*, Iterator> {
diff --git a/src/wasm.h b/src/wasm.h
index 81cb60b..2bcb1e9 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -787,32 +787,32 @@
   template<class T> bool is() const {
     static_assert(std::is_base_of<Expression, T>::value,
                   "Expression is not a base of destination type T");
-    return int(_id) == int(T::SpecificId);
+    return static_cast<int>(_id) == static_cast<int>(T::SpecificId);
   }
 
   template<class T> T* dynCast() {
     static_assert(std::is_base_of<Expression, T>::value,
                   "Expression is not a base of destination type T");
-    return int(_id) == int(T::SpecificId) ? (T*)this : nullptr;
+    return static_cast<int>(_id) == static_cast<int>(T::SpecificId) ? static_cast<T*>(this) : nullptr;
   }
 
   template<class T> const T* dynCast() const {
     static_assert(std::is_base_of<Expression, T>::value,
                   "Expression is not a base of destination type T");
-    return int(_id) == int(T::SpecificId) ? (const T*)this : nullptr;
+    return static_cast<int>(_id) == static_cast<int>(T::SpecificId) ? (const T*)this : nullptr;
   }
 
   template<class T> T* cast() {
     static_assert(std::is_base_of<Expression, T>::value,
                   "Expression is not a base of destination type T");
-    assert(int(_id) == int(T::SpecificId));
-    return (T*)this;
+    assert(static_cast<int>(_id) == static_cast<int>(T::SpecificId));
+    return static_cast<T*>(this);
   }
 
   template<class T> const T* cast() const {
     static_assert(std::is_base_of<Expression, T>::value,
                   "Expression is not a base of destination type T");
-    assert(int(_id) == int(T::SpecificId));
+    assert(static_cast<int>(_id) == static_cast<int>(T::SpecificId));
     return (const T*)this;
   }
 
@@ -2250,7 +2250,7 @@
   // debug value, indicating the information is not present.
   using DelimiterLocations = ZeroInitSmallVector<BinaryLocation, 1>;
 
-  enum DelimiterId : size_t { Else = 0, Invalid = size_t(-1) };
+  enum DelimiterId : size_t { Else = 0, Invalid = static_cast<size_t>(-1) };
 
   std::unordered_map<Expression*, DelimiterLocations> delimiters;
 
@@ -2450,7 +2450,7 @@
   Memory = 2,
   Global = 3,
   Tag = 4,
-  Invalid = uint32_t(-1)
+  Invalid = static_cast<uint32_t>(-1)
 };
 } // namespace ExternalKindImpl
 using ExternalKind = ExternalKindImpl::Kind;
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 1bf1443..02aee8c 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -121,7 +121,7 @@
   Literals contents;
   assert(string.size() % 2 == 0);
   for (size_t i = 0; i < string.size(); i += 2) {
-    int32_t u = uint8_t(string[i]) | (uint8_t(string[i + 1]) << 8);
+    int32_t u = static_cast<uint8_t>(string[i]) | (static_cast<uint8_t>(string[i + 1]) << 8);
     contents.push_back(Literal(u));
   }
   gcData = std::make_shared<GCData>(std::move(contents));
@@ -244,7 +244,7 @@
     memcpy(&lane, bits, sizeof(lane));
     for (size_t offset = 0; offset < lane_width; ++offset) {
       bytes.at(lane_index * lane_width + offset) =
-        uint8_t(lane >> (8 * offset));
+        static_cast<uint8_t>(lane >> (8 * offset));
     }
   }
   memcpy(&dest, bytes.data(), sizeof(bytes));
@@ -351,9 +351,9 @@
   }
   // Pick a simple canonical payload, and positive.
   if (input.type == Type::f32) {
-    return Literal(bit_cast<float>(uint32_t(0x7fc00000u)));
+    return Literal(bit_cast<float>(static_cast<uint32_t>(0x7fc00000u)));
   } else if (input.type == Type::f64) {
-    return Literal(bit_cast<double>(uint64_t(0x7ff8000000000000ull)));
+    return Literal(bit_cast<double>(static_cast<uint64_t>(0x7ff8000000000000ull)));
   } else {
     WASM_UNREACHABLE("unexpected type");
   }
@@ -628,7 +628,7 @@
       o << " ";
     }
     o << "0x" << std::setfill('0') << std::setw(8)
-      << uint32_t(v[i] | (v[i + 1] << 8) | (v[i + 2] << 16) | (v[i + 3] << 24));
+      << static_cast<uint32_t>(v[i] | (v[i + 1] << 8) | (v[i + 2] << 16) | (v[i + 3] << 24));
   }
   o << std::dec;
 }
@@ -751,8 +751,8 @@
             for (auto c : data->values) {
               auto u = c.getInteger();
               assert(u < 0x10000);
-              wtf16 << uint8_t(u & 0xFF);
-              wtf16 << uint8_t(u >> 8);
+              wtf16 << static_cast<uint8_t>(u & 0xFF);
+              wtf16 << static_cast<uint8_t>(u >> 8);
             }
             // Escape to ensure we have valid unicode output and to make
             // unprintable characters visible.
@@ -819,131 +819,131 @@
 
 Literal Literal::countLeadingZeroes() const {
   if (type == Type::i32) {
-    return Literal((int32_t)Bits::countLeadingZeroes(i32));
+    return Literal(Bits::countLeadingZeroes(i32));
   }
   if (type == Type::i64) {
-    return Literal((int64_t)Bits::countLeadingZeroes(i64));
+    return Literal(Bits::countLeadingZeroes(i64));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::countTrailingZeroes() const {
   if (type == Type::i32) {
-    return Literal((int32_t)Bits::countTrailingZeroes(i32));
+    return Literal(Bits::countTrailingZeroes(i32));
   }
   if (type == Type::i64) {
-    return Literal((int64_t)Bits::countTrailingZeroes(i64));
+    return Literal(Bits::countTrailingZeroes(i64));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::popCount() const {
   if (type == Type::i32) {
-    return Literal((int32_t)Bits::popCount(i32));
+    return Literal(Bits::popCount(i32));
   }
   if (type == Type::i64) {
-    return Literal((int64_t)Bits::popCount(i64));
+    return Literal(Bits::popCount(i64));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::extendToSI64() const {
   assert(type == Type::i32);
-  return Literal((int64_t)i32);
+  return Literal(static_cast<int64_t>(i32));
 }
 
 Literal Literal::extendToUI64() const {
   assert(type == Type::i32);
-  return Literal((uint64_t)(uint32_t)i32);
+  return Literal(static_cast<uint64_t>(static_cast<uint32_t>(i32)));
 }
 
 Literal Literal::extendToF64() const {
   assert(type == Type::f32);
-  return Literal(double(getf32()));
+  return Literal(static_cast<double>(getf32()));
 }
 
 Literal Literal::extendS8() const {
   if (type == Type::i32) {
-    return Literal(int32_t(int8_t(geti32() & 0xFF)));
+    return Literal(static_cast<int32_t>(static_cast<int8_t>(geti32() & 0xFF)));
   }
   if (type == Type::i64) {
-    return Literal(int64_t(int8_t(geti64() & 0xFF)));
+    return Literal(static_cast<int64_t>(static_cast<int8_t>(geti64() & 0xFF)));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::extendS16() const {
   if (type == Type::i32) {
-    return Literal(int32_t(int16_t(geti32() & 0xFFFF)));
+    return Literal(static_cast<int32_t>(static_cast<int16_t>(geti32() & 0xFFFF)));
   }
   if (type == Type::i64) {
-    return Literal(int64_t(int16_t(geti64() & 0xFFFF)));
+    return Literal(static_cast<int64_t>(static_cast<int16_t>(geti64() & 0xFFFF)));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::extendS32() const {
   if (type == Type::i64) {
-    return Literal(int64_t(int32_t(geti64() & 0xFFFFFFFF)));
+    return Literal(static_cast<int64_t>(static_cast<int32_t>(geti64() & 0xFFFFFFFF)));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::wrapToI32() const {
   assert(type == Type::i64);
-  return Literal((int32_t)i64);
+  return Literal(static_cast<int32_t>(i64));
 }
 
 Literal Literal::convertSIToF16() const {
   if (type == Type::i32) {
-    return Literal(fp16_ieee_from_fp32_value(float(i32)));
+    return Literal(fp16_ieee_from_fp32_value(static_cast<float>(i32)));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::convertUIToF16() const {
   if (type == Type::i32) {
-    return Literal(fp16_ieee_from_fp32_value(float(uint16_t(i32))));
+    return Literal(fp16_ieee_from_fp32_value(static_cast<float>(static_cast<uint16_t>(i32))));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::convertSIToF32() const {
   if (type == Type::i32) {
-    return Literal(float(i32));
+    return Literal(static_cast<float>(i32));
   }
   if (type == Type::i64) {
-    return Literal(float(i64));
+    return Literal(static_cast<float>(i64));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::convertUIToF32() const {
   if (type == Type::i32) {
-    return Literal(float(uint32_t(i32)));
+    return Literal(static_cast<float>(static_cast<uint32_t>(i32)));
   }
   if (type == Type::i64) {
-    return Literal(float(uint64_t(i64)));
+    return Literal(static_cast<float>(static_cast<uint64_t>(i64)));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::convertSIToF64() const {
   if (type == Type::i32) {
-    return Literal(double(i32));
+    return Literal(static_cast<double>(i32));
   }
   if (type == Type::i64) {
-    return Literal(double(i64));
+    return Literal(static_cast<double>(i64));
   }
   WASM_UNREACHABLE("invalid type");
 }
 
 Literal Literal::convertUIToF64() const {
   if (type == Type::i32) {
-    return Literal(double(uint32_t(i32)));
+    return Literal(static_cast<double>(static_cast<uint32_t>(i32)));
   }
   if (type == Type::i64) {
-    return Literal(double(uint64_t(i64)));
+    return Literal(static_cast<double>(static_cast<uint64_t>(i64)));
   }
   WASM_UNREACHABLE("invalid type");
 }
@@ -1044,13 +1044,13 @@
 Literal Literal::eqz() const {
   switch (type.getBasic()) {
     case Type::i32:
-      return eq(Literal(int32_t(0)));
+      return eq(Literal(static_cast<int32_t>(0)));
     case Type::i64:
-      return eq(Literal(int64_t(0)));
+      return eq(Literal(static_cast<int64_t>(0)));
     case Type::f32:
-      return eq(Literal(float(0)));
+      return eq(Literal(static_cast<float>(0)));
     case Type::f64:
-      return eq(Literal(double(0)));
+      return eq(Literal(static_cast<double>(0)));
     case Type::v128:
     case Type::none:
     case Type::unreachable:
@@ -1062,13 +1062,13 @@
 Literal Literal::neg() const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(-uint32_t(i32));
+      return Literal(-static_cast<uint32_t>(i32));
     case Type::i64:
-      return Literal(-uint64_t(i64));
+      return Literal(-static_cast<uint64_t>(i64));
     case Type::f32:
       return Literal(i32 ^ 0x80000000).castToF32();
     case Type::f64:
-      return Literal(int64_t(i64 ^ 0x8000000000000000ULL)).castToF64();
+      return Literal(static_cast<int64_t>(i64 ^ 0x8000000000000000ULL)).castToF64();
     case Type::v128:
     case Type::none:
     case Type::unreachable:
@@ -1092,7 +1092,7 @@
     case Type::f32:
       return Literal(i32 & 0x7fffffff).castToF32();
     case Type::f64:
-      return Literal(int64_t(i64 & 0x7fffffffffffffffULL)).castToF64();
+      return Literal(static_cast<int64_t>(i64 & 0x7fffffffffffffffULL)).castToF64();
     case Type::v128:
     case Type::none:
     case Type::unreachable:
@@ -1159,10 +1159,10 @@
 Literal Literal::demote() const {
   auto f64 = getf64();
   if (std::isnan(f64)) {
-    return Literal(float(f64));
+    return Literal(static_cast<float>(f64));
   }
   if (std::isinf(f64)) {
-    return Literal(float(f64));
+    return Literal(static_cast<float>(f64));
   }
   // when close to the limit, but still truncatable to a valid value, do that
   // see
@@ -1181,7 +1181,7 @@
   if (f64 > std::numeric_limits<float>::max()) {
     return Literal(std::numeric_limits<float>::infinity());
   }
-  return Literal(float(getf64()));
+  return Literal(static_cast<float>(getf64()));
 }
 
 Literal Literal::add(const Literal& other) const {
@@ -1205,9 +1205,9 @@
 Literal Literal::sub(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32) - uint32_t(other.i32));
+      return Literal(static_cast<uint32_t>(i32) - static_cast<uint32_t>(other.i32));
     case Type::i64:
-      return Literal(uint64_t(i64) - uint64_t(other.i64));
+      return Literal(static_cast<uint64_t>(i64) - static_cast<uint64_t>(other.i64));
     case Type::f32:
       return standardizeNaN(Literal(getf32() - other.getf32()));
     case Type::f64:
@@ -1293,18 +1293,18 @@
 
 Literal Literal::q15MulrSatSI16(const Literal& other) const {
   int64_t value =
-    (int64_t(geti32()) * int64_t(other.geti32()) + 0x4000LL) >> 15LL;
+    (static_cast<int64_t>(geti32()) * static_cast<int64_t>(other.geti32()) + 0x4000LL) >> 15LL;
   int64_t lower = std::numeric_limits<int16_t>::min();
   int64_t upper = std::numeric_limits<int16_t>::max();
-  return Literal(int16_t(std::min(std::max(value, lower), upper)));
+  return Literal(static_cast<int16_t>(std::min(std::max(value, lower), upper)));
 }
 
 Literal Literal::mul(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32) * uint32_t(other.i32));
+      return Literal(static_cast<uint32_t>(i32) * static_cast<uint32_t>(other.i32));
     case Type::i64:
-      return Literal(uint64_t(i64) * uint64_t(other.i64));
+      return Literal(static_cast<uint64_t>(i64) * static_cast<uint64_t>(other.i64));
     case Type::f32:
       return standardizeNaN(Literal(getf32() * other.getf32()));
     case Type::f64:
@@ -1390,9 +1390,9 @@
 Literal Literal::divU(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32) / uint32_t(other.i32));
+      return Literal(static_cast<uint32_t>(i32) / static_cast<uint32_t>(other.i32));
     case Type::i64:
-      return Literal(uint64_t(i64) / uint64_t(other.i64));
+      return Literal(static_cast<uint64_t>(i64) / static_cast<uint64_t>(other.i64));
     default:
       WASM_UNREACHABLE("unexpected type");
   }
@@ -1412,9 +1412,9 @@
 Literal Literal::remU(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32) % uint32_t(other.i32));
+      return Literal(static_cast<uint32_t>(i32) % static_cast<uint32_t>(other.i32));
     case Type::i64:
-      return Literal(uint64_t(i64) % uint64_t(other.i64));
+      return Literal(static_cast<uint64_t>(i64) % static_cast<uint64_t>(other.i64));
     default:
       WASM_UNREACHABLE("unexpected type");
   }
@@ -1427,10 +1427,10 @@
   return geti32() > other.geti32() ? *this : other;
 }
 Literal Literal::minUInt(const Literal& other) const {
-  return uint32_t(geti32()) < uint32_t(other.geti32()) ? *this : other;
+  return static_cast<uint32_t>(geti32()) < static_cast<uint32_t>(other.geti32()) ? *this : other;
 }
 Literal Literal::maxUInt(const Literal& other) const {
-  return uint32_t(geti32()) > uint32_t(other.geti32()) ? *this : other;
+  return static_cast<uint32_t>(geti32()) > static_cast<uint32_t>(other.geti32()) ? *this : other;
 }
 
 Literal Literal::avgrUInt(const Literal& other) const {
@@ -1475,10 +1475,10 @@
 Literal Literal::shl(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32)
+      return Literal(static_cast<uint32_t>(i32)
                      << Bits::getEffectiveShifts(other.i32, Type::i32));
     case Type::i64:
-      return Literal(uint64_t(i64)
+      return Literal(static_cast<uint64_t>(i64)
                      << Bits::getEffectiveShifts(other.i64, Type::i64));
     default:
       WASM_UNREACHABLE("unexpected type");
@@ -1499,10 +1499,10 @@
 Literal Literal::shrU(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32) >>
+      return Literal(static_cast<uint32_t>(i32) >>
                      Bits::getEffectiveShifts(other.i32, Type::i32));
     case Type::i64:
-      return Literal(uint64_t(i64) >>
+      return Literal(static_cast<uint64_t>(i64) >>
                      Bits::getEffectiveShifts(other.i64, Type::i64));
     default:
       WASM_UNREACHABLE("unexpected type");
@@ -1512,9 +1512,9 @@
 Literal Literal::rotL(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(Bits::rotateLeft(uint32_t(i32), uint32_t(other.i32)));
+      return Literal(Bits::rotateLeft(static_cast<uint32_t>(i32), static_cast<uint32_t>(other.i32)));
     case Type::i64:
-      return Literal(Bits::rotateLeft(uint64_t(i64), uint64_t(other.i64)));
+      return Literal(Bits::rotateLeft(static_cast<uint64_t>(i64), static_cast<uint64_t>(other.i64)));
     default:
       WASM_UNREACHABLE("unexpected type");
   }
@@ -1523,9 +1523,9 @@
 Literal Literal::rotR(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(Bits::rotateRight(uint32_t(i32), uint32_t(other.i32)));
+      return Literal(Bits::rotateRight(static_cast<uint32_t>(i32), static_cast<uint32_t>(other.i32)));
     case Type::i64:
-      return Literal(Bits::rotateRight(uint64_t(i64), uint64_t(other.i64)));
+      return Literal(Bits::rotateRight(static_cast<uint64_t>(i64), static_cast<uint64_t>(other.i64)));
     default:
       WASM_UNREACHABLE("unexpected type");
   }
@@ -1581,9 +1581,9 @@
 Literal Literal::ltU(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32) < uint32_t(other.i32));
+      return Literal(static_cast<uint32_t>(i32) < static_cast<uint32_t>(other.i32));
     case Type::i64:
-      return Literal(uint64_t(i64) < uint64_t(other.i64));
+      return Literal(static_cast<uint64_t>(i64) < static_cast<uint64_t>(other.i64));
     default:
       WASM_UNREACHABLE("unexpected type");
   }
@@ -1614,9 +1614,9 @@
 Literal Literal::leU(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32) <= uint32_t(other.i32));
+      return Literal(static_cast<uint32_t>(i32) <= static_cast<uint32_t>(other.i32));
     case Type::i64:
-      return Literal(uint64_t(i64) <= uint64_t(other.i64));
+      return Literal(static_cast<uint64_t>(i64) <= static_cast<uint64_t>(other.i64));
     default:
       WASM_UNREACHABLE("unexpected type");
   }
@@ -1647,9 +1647,9 @@
 Literal Literal::gtU(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32) > uint32_t(other.i32));
+      return Literal(static_cast<uint32_t>(i32) > static_cast<uint32_t>(other.i32));
     case Type::i64:
-      return Literal(uint64_t(i64) > uint64_t(other.i64));
+      return Literal(static_cast<uint64_t>(i64) > static_cast<uint64_t>(other.i64));
     default:
       WASM_UNREACHABLE("unexpected type");
   }
@@ -1680,9 +1680,9 @@
 Literal Literal::geU(const Literal& other) const {
   switch (type.getBasic()) {
     case Type::i32:
-      return Literal(uint32_t(i32) >= uint32_t(other.i32));
+      return Literal(static_cast<uint32_t>(i32) >= static_cast<uint32_t>(other.i32));
     case Type::i64:
-      return Literal(uint64_t(i64) >= uint64_t(other.i64));
+      return Literal(static_cast<uint64_t>(i64) >= static_cast<uint64_t>(other.i64));
     default:
       WASM_UNREACHABLE("unexpected type");
   }
@@ -2154,10 +2154,10 @@
   auto lanes = getLanesI32x4();
   for (size_t i = 0; i < 4; ++i) {
     if (lanes[i].geti32() != 0) {
-      return Literal(int32_t(1));
+      return Literal(static_cast<int32_t>(1));
     }
   }
-  return Literal(int32_t(0));
+  return Literal(static_cast<int32_t>(0));
 }
 
 template<int Lanes, LaneArray<Lanes> (Literal::*IntoLanes)() const>
@@ -2165,10 +2165,10 @@
   LaneArray<Lanes> lanes = (val.*IntoLanes)();
   for (size_t i = 0; i < Lanes; ++i) {
     if (lanes[i] == Literal::makeZero(lanes[i].type)) {
-      return Literal(int32_t(0));
+      return Literal(static_cast<int32_t>(0));
     }
   }
-  return Literal(int32_t(1));
+  return Literal(static_cast<int32_t>(1));
 }
 
 template<int Lanes, LaneArray<Lanes> (Literal::*IntoLanes)() const>
@@ -2224,7 +2224,7 @@
   LaneArray<Lanes> lanes = (vec.*IntoLanes)();
   for (size_t i = 0; i < Lanes; ++i) {
     lanes[i] =
-      (lanes[i].*ShiftOp)(Literal(int32_t(shift.geti32() % lane_bits)));
+      (lanes[i].*ShiftOp)(Literal(static_cast<int32_t>(shift.geti32() % lane_bits)));
   }
   return Literal(lanes);
 }
@@ -2274,7 +2274,7 @@
   LaneArray<Lanes> lanes = (val.*IntoLanes)();
   LaneArray<Lanes> other_lanes = (other.*IntoLanes)();
   for (size_t i = 0; i < Lanes; ++i) {
-    lanes[i] = (lanes[i].*CompareOp)(other_lanes[i]) == Literal(int32_t(1))
+    lanes[i] = (lanes[i].*CompareOp)(other_lanes[i]) == Literal(static_cast<int32_t>(1))
                  ? Literal(LaneT(-1))
                  : Literal(LaneT(0));
   }
@@ -2678,7 +2678,7 @@
   LaneArray<Lanes * Factor> rhs = (right.*IntoLanes)();
   LaneArray<Lanes> result;
   for (size_t i = 0; i < Lanes; ++i) {
-    result[i] = Literal(int32_t(0));
+    result[i] = Literal(static_cast<int32_t>(0));
     for (size_t j = 0; j < Factor; ++j) {
       result[i] = result[i].add(lhs[i * Factor + j].mul(rhs[i * Factor + j]));
     }
@@ -2733,7 +2733,7 @@
   } else if (val < WideT(std::numeric_limits<T>::min())) {
     val = std::numeric_limits<T>::min();
   }
-  return Literal(int32_t(val));
+  return Literal(static_cast<int32_t>(val));
 }
 
 template<size_t Lanes,
@@ -2781,7 +2781,7 @@
   LaneArray<2> result;
   for (size_t i = 0; i < 2; ++i) {
     size_t idx = (Side == LaneOrder::Low) ? i : i + 2;
-    result[i] = Literal((double)lanes[idx].getf32());
+    result[i] = Literal(static_cast<double>(lanes[idx].getf32()));
   }
   return Literal(result);
 }
@@ -2917,7 +2917,7 @@
   LaneArray<16> result;
   for (size_t i = 0; i < 16; ++i) {
     size_t index = indices[i].geti32();
-    result[i] = index >= 16 ? Literal(int32_t(0)) : lanes[index];
+    result[i] = index >= 16 ? Literal(static_cast<int32_t>(0)) : lanes[index];
   }
   return Literal(result);
 }
diff --git a/src/wasm/parsing.cpp b/src/wasm/parsing.cpp
index 5d34da7..39dcc4c 100644
--- a/src/wasm/parsing.cpp
+++ b/src/wasm/parsing.cpp
@@ -27,7 +27,7 @@
   o << "parse exception: ";
   Colors::green(o);
   o << text;
-  if (line != size_t(-1)) {
+  if (line != static_cast<size_t>(-1)) {
     Colors::normal(o);
     o << " (at " << line << ":" << col << ")";
   }
diff --git a/src/wasm/source-map.cpp b/src/wasm/source-map.cpp
index 4634113..5f9e879 100644
--- a/src/wasm/source-map.cpp
+++ b/src/wasm/source-map.cpp
@@ -200,7 +200,7 @@
       throw MapParseException("VLQ value too large");
     }
   }
-  return value & 1 ? -int32_t(value >> 1) : int32_t(value >> 1);
+  return value & 1 ? -static_cast<int32_t>(value >> 1) : static_cast<int32_t>(value >> 1);
 }
 
 } // namespace wasm
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 898110c..da0e82b 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -101,8 +101,8 @@
 }
 
 void WasmBinaryWriter::writeHeader() {
-  o << int32_t(BinaryConsts::Magic); // magic number \0asm
-  o << int32_t(BinaryConsts::Version);
+  o << static_cast<int32_t>(BinaryConsts::Magic); // magic number \0asm
+  o << static_cast<int32_t>(BinaryConsts::Version);
 }
 
 int32_t WasmBinaryWriter::writeU32LEBPlaceholder() {
@@ -118,11 +118,11 @@
   std::optional<uint8_t> pageSizeLog2) {
   uint8_t actualPageSizeLog2 =
     pageSizeLog2 ? *pageSizeLog2 : Memory::kDefaultPageSizeLog2;
-  uint32_t flags = (hasMaximum ? (uint32_t)BinaryConsts::HasMaximum : 0U) |
-                   (shared ? (uint32_t)BinaryConsts::IsShared : 0U) |
-                   (is64 ? (uint32_t)BinaryConsts::Is64 : 0U) |
+  uint32_t flags = (hasMaximum ? static_cast<uint32_t>(BinaryConsts::HasMaximum) : 0U) |
+                   (shared ? static_cast<uint32_t>(BinaryConsts::IsShared) : 0U) |
+                   (is64 ? static_cast<uint32_t>(BinaryConsts::Is64) : 0U) |
                    (actualPageSizeLog2 != Memory::kDefaultPageSizeLog2
-                      ? (uint32_t)BinaryConsts::HasCustomPageSize
+                      ? static_cast<uint32_t>(BinaryConsts::HasCustomPageSize)
                       : 0U);
   o << U32LEB(flags);
   if (is64) {
@@ -142,7 +142,7 @@
 }
 
 template<typename T> int32_t WasmBinaryWriter::startSection(T code) {
-  o << uint8_t(code);
+  o << static_cast<uint8_t>(code);
   if (sourceMap) {
     sourceMapLocationsSizeAtSectionStart = sourceMapLocations.size();
   }
@@ -266,16 +266,16 @@
     // size 1 are implicit, so only emit a group header for larger groups.
     auto currGroup = type.getRecGroup();
     if (lastGroup != currGroup && currGroup.size() > 1) {
-      o << uint8_t(BinaryConsts::EncodedType::Rec) << U32LEB(currGroup.size());
+      o << static_cast<uint8_t>(BinaryConsts::EncodedType::Rec) << U32LEB(currGroup.size());
     }
     lastGroup = currGroup;
     // Emit the type definition.
     auto super = type.getDeclaredSuperType();
     if (super || type.isOpen()) {
       if (type.isOpen()) {
-        o << uint8_t(BinaryConsts::EncodedType::Sub);
+        o << static_cast<uint8_t>(BinaryConsts::EncodedType::Sub);
       } else {
-        o << uint8_t(BinaryConsts::EncodedType::SubFinal);
+        o << static_cast<uint8_t>(BinaryConsts::EncodedType::SubFinal);
       }
       if (super) {
         o << U32LEB(1);
@@ -285,19 +285,19 @@
       }
     }
     if (type.isShared()) {
-      o << uint8_t(BinaryConsts::EncodedType::Shared);
+      o << static_cast<uint8_t>(BinaryConsts::EncodedType::Shared);
     }
     if (auto desc = type.getDescribedType()) {
-      o << uint8_t(BinaryConsts::EncodedType::Describes);
+      o << static_cast<uint8_t>(BinaryConsts::EncodedType::Describes);
       writeHeapType(*desc, Inexact);
     }
     if (auto desc = type.getDescriptorType()) {
-      o << uint8_t(BinaryConsts::EncodedType::Descriptor);
+      o << static_cast<uint8_t>(BinaryConsts::EncodedType::Descriptor);
       writeHeapType(*desc, Inexact);
     }
     switch (type.getKind()) {
       case HeapTypeKind::Func: {
-        o << uint8_t(BinaryConsts::EncodedType::Func);
+        o << static_cast<uint8_t>(BinaryConsts::EncodedType::Func);
         auto sig = type.getSignature();
         for (auto& sigType : {sig.params, sig.results}) {
           o << U32LEB(sigType.size());
@@ -308,7 +308,7 @@
         break;
       }
       case HeapTypeKind::Struct: {
-        o << uint8_t(BinaryConsts::EncodedType::Struct);
+        o << static_cast<uint8_t>(BinaryConsts::EncodedType::Struct);
         auto fields = type.getStruct().fields;
         o << U32LEB(fields.size());
         for (const auto& field : fields) {
@@ -317,11 +317,11 @@
         break;
       }
       case HeapTypeKind::Array:
-        o << uint8_t(BinaryConsts::EncodedType::Array);
+        o << static_cast<uint8_t>(BinaryConsts::EncodedType::Array);
         writeField(type.getArray().element);
         break;
       case HeapTypeKind::Cont:
-        o << uint8_t(BinaryConsts::EncodedType::Cont);
+        o << static_cast<uint8_t>(BinaryConsts::EncodedType::Cont);
         writeHeapType(type.getContinuation().type, Inexact);
         break;
       case HeapTypeKind::Basic:
@@ -352,19 +352,19 @@
   });
   ModuleUtils::iterImportedGlobals(*wasm, [&](Global* global) {
     writeImportHeader(global);
-    o << U32LEB(int32_t(ExternalKind::Global));
+    o << U32LEB(static_cast<int32_t>(ExternalKind::Global));
     writeType(global->type);
     o << U32LEB(global->mutable_);
   });
   ModuleUtils::iterImportedTags(*wasm, [&](Tag* tag) {
     writeImportHeader(tag);
-    o << U32LEB(int32_t(ExternalKind::Tag));
-    o << uint8_t(0); // Reserved 'attribute' field. Always 0.
+    o << U32LEB(static_cast<int32_t>(ExternalKind::Tag));
+    o << static_cast<uint8_t>(0); // Reserved 'attribute' field. Always 0.
     o << U32LEB(getTypeIndex(tag->type));
   });
   ModuleUtils::iterImportedMemories(*wasm, [&](Memory* memory) {
     writeImportHeader(memory);
-    o << U32LEB(int32_t(ExternalKind::Memory));
+    o << U32LEB(static_cast<int32_t>(ExternalKind::Memory));
     writeResizableLimits(memory->initial,
                          memory->max,
                          memory->hasMax(),
@@ -374,7 +374,7 @@
   });
   ModuleUtils::iterImportedTables(*wasm, [&](Table* table) {
     writeImportHeader(table);
-    o << U32LEB(int32_t(ExternalKind::Table));
+    o << U32LEB(static_cast<int32_t>(ExternalKind::Table));
     writeType(table->type);
     writeResizableLimits(table->initial,
                          table->max,
@@ -617,7 +617,7 @@
         // look something like this:
         //
         //   auto parentIndex = getGlobalIndex(get->name);
-        //   o << int8_t(BinaryConsts::GlobalGet) << U32LEB(parentIndex + i);
+        //   o << static_cast<int8_t>(BinaryConsts::GlobalGet) << U32LEB(parentIndex + i);
         //
         // That is, we must emit the instruction here, and not defer to
         // writeExpression, as writeExpression writes an entire expression at a
@@ -626,7 +626,7 @@
         // one tuple global to another, we disallow this.
         WASM_UNREACHABLE("unsupported tuple global operation");
       }
-      o << int8_t(BinaryConsts::End);
+      o << static_cast<int8_t>(BinaryConsts::End);
       ++i;
     }
   });
@@ -641,7 +641,7 @@
   o << U32LEB(wasm->exports.size());
   for (auto& curr : wasm->exports) {
     writeInlineString(curr->name.str);
-    o << U32LEB(int32_t(curr->kind));
+    o << U32LEB(static_cast<int32_t>(curr->kind));
     switch (curr->kind) {
       case ExternalKind::Function:
         o << U32LEB(getFunctionIndex(*curr->getInternalName()));
@@ -702,7 +702,7 @@
         o << U32LEB(memoryIndex);
       }
       writeExpression(segment->offset);
-      o << int8_t(BinaryConsts::End);
+      o << static_cast<int8_t>(BinaryConsts::End);
     }
     writeInlineBuffer(segment->data.data(), segment->data.size());
   }
@@ -847,7 +847,7 @@
         o << U32LEB(tableIdx);
       }
       writeExpression(segment->offset);
-      o << int8_t(BinaryConsts::End);
+      o << static_cast<int8_t>(BinaryConsts::End);
     }
 
     if (isPassive || hasTableIndex) {
@@ -863,7 +863,7 @@
     if (usesExpressions) {
       for (auto* item : segment->data) {
         writeExpression(item);
-        o << int8_t(BinaryConsts::End);
+        o << static_cast<int8_t>(BinaryConsts::End);
       }
     } else {
       for (auto& item : segment->data) {
@@ -894,7 +894,7 @@
   auto num = importInfo->getNumDefinedTags();
   o << U32LEB(num);
   ModuleUtils::iterDefinedTags(*wasm, [&](Tag* tag) {
-    o << uint8_t(0); // Reserved 'attribute' field. Always 0.
+    o << static_cast<uint8_t>(0); // Reserved 'attribute' field. Always 0.
     o << U32LEB(getTypeIndex(tag->type));
   });
 
@@ -1347,12 +1347,12 @@
     value >>= 5;
     if (!value) {
       // last VLQ digit -- base64 codes 'A'..'Z', 'a'..'f'
-      out << char(digit < 26 ? 'A' + digit : 'a' + digit - 26);
+      out << static_cast<char>(digit < 26 ? 'A' + digit : 'a' + digit - 26);
       break;
     }
     // more VLG digit will follow -- add continuation bit (0x20),
     // base64 codes 'g'..'z', '0'..'9', '+', '/'
-    out << char(digit < 20    ? 'g' + digit
+    out << static_cast<char>(digit < 20    ? 'g' + digit
                 : digit < 30  ? '0' + digit - 20
                 : digit == 30 ? '+'
                               : '/');
@@ -1370,21 +1370,21 @@
     if (lastOffset > 0) {
       *sourceMap << ",";
     }
-    writeBase64VLQ(*sourceMap, int32_t(offset - lastOffset));
+    writeBase64VLQ(*sourceMap, static_cast<int32_t>(offset - lastOffset));
     lastOffset = offset;
     if (loc) {
-      writeBase64VLQ(*sourceMap, int32_t(loc->fileIndex - lastFileIndex));
+      writeBase64VLQ(*sourceMap, static_cast<int32_t>(loc->fileIndex - lastFileIndex));
       lastFileIndex = loc->fileIndex;
 
-      writeBase64VLQ(*sourceMap, int32_t(loc->lineNumber - lastLineNumber));
+      writeBase64VLQ(*sourceMap, static_cast<int32_t>(loc->lineNumber - lastLineNumber));
       lastLineNumber = loc->lineNumber;
 
-      writeBase64VLQ(*sourceMap, int32_t(loc->columnNumber - lastColumnNumber));
+      writeBase64VLQ(*sourceMap, static_cast<int32_t>(loc->columnNumber - lastColumnNumber));
       lastColumnNumber = loc->columnNumber;
 
       if (loc->symbolNameIndex) {
         writeBase64VLQ(*sourceMap,
-                       int32_t(*loc->symbolNameIndex - lastSymbolNameIndex));
+                       static_cast<int32_t>(*loc->symbolNameIndex - lastSymbolNameIndex));
         lastSymbolNameIndex = *loc->symbolNameIndex;
       }
     }
@@ -1414,7 +1414,7 @@
   auto start = startSection(BinaryConsts::Custom);
   writeInlineString(section.name.c_str());
   for (size_t i = 0; i < section.data.size(); i++) {
-    o << uint8_t(section.data[i]);
+    o << static_cast<uint8_t>(section.data[i]);
   }
   finishSection(start);
 }
@@ -1492,7 +1492,7 @@
   writeInlineString(BinaryConsts::CustomSections::TargetFeatures);
   o << U32LEB(features.size());
   for (auto& f : features) {
-    o << uint8_t(BinaryConsts::FeatureUsed);
+    o << static_cast<uint8_t>(BinaryConsts::FeatureUsed);
     writeInlineString(f);
   }
   finishSection(start);
@@ -1730,7 +1730,7 @@
   BufferWithRandomAccess buffer;
 
   // We found data: emit the section.
-  buffer << uint8_t(BinaryConsts::Custom);
+  buffer << static_cast<uint8_t>(BinaryConsts::Custom);
   auto lebPos = buffer.writeU32LEBPlaceholder();
   buffer.writeInlineString(sectionName.str);
 
@@ -1766,7 +1766,7 @@
       assert(annotation.branchLikely);
 
       // Hint contents: likely or not.
-      buffer << U32LEB(int(*annotation.branchLikely));
+      buffer << U32LEB(static_cast<int>(*annotation.branchLikely));
     });
 }
 
@@ -1816,7 +1816,7 @@
 
 void WasmBinaryWriter::writeData(const char* data, size_t size) {
   for (size_t i = 0; i < size; i++) {
-    o << int8_t(data[i]);
+    o << static_cast<int8_t>(data[i]);
   }
 }
 
@@ -1849,7 +1849,7 @@
       continue;
     }
     unescaped.push_back(
-      char((decodeHexNibble(name[i]) << 4) | decodeHexNibble(name[i + 1])));
+      static_cast<char>((decodeHexNibble(name[i]) << 4) | decodeHexNibble(name[i + 1])));
     i += 2;
   }
   writeInlineString({unescaped.data(), unescaped.size()});
@@ -1956,7 +1956,7 @@
   }
   assert(!type.isBasic() || exactness == Inexact);
   if (exactness == Exact) {
-    o << uint8_t(BinaryConsts::EncodedType::Exact);
+    o << static_cast<uint8_t>(BinaryConsts::EncodedType::Exact);
   }
   if (!type.isBasic()) {
     o << S64LEB(getTypeIndex(type)); // TODO: Actually s33
@@ -1965,7 +1965,7 @@
 
   int ret = 0;
   if (type.isShared()) {
-    o << uint8_t(BinaryConsts::EncodedType::Shared);
+    o << static_cast<uint8_t>(BinaryConsts::EncodedType::Shared);
   }
   switch (type.getBasic(Unshared)) {
     case HeapType::ext:
@@ -2052,7 +2052,7 @@
       break;
   }
   if (isRMW) {
-    o << uint8_t((code << 4) | code);
+    o << static_cast<uint8_t>((code << 4) | code);
   } else {
     o << code;
   }
@@ -2079,7 +2079,7 @@
   while (more()) {
     uint8_t sectionCode = getInt8();
     uint32_t payloadLen = getU32LEB();
-    if (uint64_t(pos) + uint64_t(payloadLen) > input.size()) {
+    if (static_cast<uint64_t>(pos) + static_cast<uint64_t>(payloadLen) > input.size()) {
       throwError("Section extends beyond end of input");
     }
     auto oldPos = pos;
@@ -2130,7 +2130,7 @@
   while (more()) {
     uint8_t sectionCode = getInt8();
     uint32_t payloadLen = getU32LEB();
-    if (uint64_t(pos) + uint64_t(payloadLen) > input.size()) {
+    if (static_cast<uint64_t>(pos) + static_cast<uint64_t>(payloadLen) > input.size()) {
       throwError("Section extends beyond end of input");
     }
 
@@ -2289,20 +2289,20 @@
 }
 
 uint16_t WasmBinaryReader::getInt16() {
-  auto ret = uint16_t(getInt8());
-  ret |= uint16_t(getInt8()) << 8;
+  auto ret = static_cast<uint16_t>(getInt8());
+  ret |= static_cast<uint16_t>(getInt8()) << 8;
   return ret;
 }
 
 uint32_t WasmBinaryReader::getInt32() {
-  auto ret = uint32_t(getInt16());
-  ret |= uint32_t(getInt16()) << 16;
+  auto ret = static_cast<uint32_t>(getInt16());
+  ret |= static_cast<uint32_t>(getInt16()) << 16;
   return ret;
 }
 
 uint64_t WasmBinaryReader::getInt64() {
-  auto ret = uint64_t(getInt32());
-  ret |= uint64_t(getInt32()) << 32;
+  auto ret = static_cast<uint64_t>(getInt32());
+  ret |= static_cast<uint64_t>(getInt32()) << 32;
   return ret;
 }
 
@@ -2349,13 +2349,13 @@
 
 int32_t WasmBinaryReader::getS32LEB() {
   S32LEB ret;
-  ret.read([&]() { return (int8_t)getInt8(); });
+  ret.read([&]() { return static_cast<int8_t>(getInt8()); });
   return ret.value;
 }
 
 int64_t WasmBinaryReader::getS64LEB() {
   S64LEB ret;
-  ret.read([&]() { return (int8_t)getInt8(); });
+  ret.read([&]() { return static_cast<int8_t>(getInt8()); });
   return ret.value;
 }
 
@@ -2518,7 +2518,7 @@
   }
   // Single heap types are negative; heap type indices are non-negative
   if (type >= 0) {
-    if (size_t(type) >= types.size()) {
+    if (static_cast<size_t>(type) >= types.size()) {
       throwError("invalid type index: " + std::to_string(type));
     }
     return {types[type], exactness};
@@ -2664,10 +2664,10 @@
       htCode = getS64LEB(); // TODO: Actually s33
     }
     if (htCode >= 0) {
-      if (size_t(htCode) >= builder.size()) {
+      if (static_cast<size_t>(htCode) >= builder.size()) {
         throwError("invalid type index: " + std::to_string(htCode));
       }
-      return {builder.getTempHeapType(size_t(htCode)), exactness};
+      return {builder.getTempHeapType(static_cast<size_t>(htCode)), exactness};
     }
     if (exactness == Exact) {
       throwError("invalid type index: " + std::to_string(htCode));
@@ -2980,7 +2980,7 @@
         readPageSizeLog2 != Memory::kDefaultPageSizeLog2) {
       throwError("Memory page size is only allowed to be 1 or 64 KiB");
     }
-    pageSizeLog2 = (uint8_t)readPageSizeLog2;
+    pageSizeLog2 = static_cast<uint8_t>(readPageSizeLog2);
   }
 }
 
@@ -5196,8 +5196,8 @@
     }
     // replace non-idchar with `\xx` escape
     escaped.push_back('\\');
-    escaped.push_back(formatNibble((unsigned char)c >> 4));
-    escaped.push_back(formatNibble((unsigned char)c & 15));
+    escaped.push_back(formatNibble(static_cast<unsigned char>(c) >> 4));
+    escaped.push_back(formatNibble(static_cast<unsigned char>(c) & 15));
   }
   return escaped;
 }
diff --git a/src/wasm/wasm-debug.cpp b/src/wasm/wasm-debug.cpp
index 0da9788..c4d10c9 100644
--- a/src/wasm/wasm-debug.cpp
+++ b/src/wasm/wasm-debug.cpp
@@ -301,7 +301,7 @@
       // In wasm32 we have 32-bit addresses, and the delta here might be
       // negative (note that SData is 64-bit, as LLVM supports 64-bit
       // addresses too).
-      item.SData = int32_t(line - old.line);
+      item.SData = static_cast<int32_t>(line - old.line);
       newOpcodes.push_back(item);
     }
     if (col != old.col) {
@@ -678,7 +678,7 @@
 // on the DWARF section. For now, support them all, but TODO stop supporting 0,
 // as there are apparently some possible corner cases where 0 is a valid value.
 static bool isTombstone(uint32_t x) {
-  return x == 0 || x == uint32_t(-1) || x == uint32_t(-2);
+  return x == 0 || x == static_cast<uint32_t>(-1) || x == static_cast<uint32_t>(-2);
 }
 
 // Update debug lines, and update the locationUpdater with debug line offset
@@ -748,7 +748,7 @@
           sequenceId++;
           // We assume the number of sequences can fit in 32 bits, and -1 is
           // an invalid value.
-          assert(sequenceId != uint32_t(-1));
+          assert(sequenceId != static_cast<uint32_t>(-1));
           state = LineState(table, sequenceId);
         }
       }
diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp
index 4c450bd..dc10468 100644
--- a/src/wasm/wasm-emscripten.cpp
+++ b/src/wasm/wasm-emscripten.cpp
@@ -57,7 +57,7 @@
   return nullptr;
 }
 
-const Address UNKNOWN_OFFSET(uint32_t(-1));
+const Address UNKNOWN_OFFSET(static_cast<uint32_t>(-1));
 
 std::string escape(std::string code) {
   // replace newlines quotes with escaped newlines
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index abb47ee..67b1942 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -73,7 +73,7 @@
     // There is no value-producing or unreachable expression.
     return {};
   }
-  if (unsigned(index) == stack.size() - 1) {
+  if (static_cast<unsigned>(index) == stack.size() - 1) {
     // Value-producing expression already on top of the stack.
     return HoistedVal{Index(index), nullptr};
   }
@@ -2303,7 +2303,7 @@
   ArrayNew curr;
   curr.type = Type(type, NonNullable, Exact);
   // Differentiate from array.new_default with dummy initializer.
-  curr.init = (Expression*)0x01;
+  curr.init = reinterpret_cast<Expression*>(0x01);
   CHECK_ERR(visitArrayNew(&curr));
   push(builder.makeArrayNew(type, curr.size, curr.init));
   return Ok{};
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index bfe2df1..57f14cf 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -225,11 +225,11 @@
 
 HeapTypeInfo* getHeapTypeInfo(HeapType ht) {
   assert(!ht.isBasic());
-  return (HeapTypeInfo*)ht.getID();
+  return reinterpret_cast<HeapTypeInfo*>(ht.getID());
 }
 
 HeapType asHeapType(std::unique_ptr<HeapTypeInfo>& info) {
-  return HeapType(uintptr_t(info.get()));
+  return HeapType(reinterpret_cast<uintptr_t>(info.get()));
 }
 
 bool isTemp(HeapType type) {
@@ -397,7 +397,7 @@
     return a;
   }
   // Canonicalize to have `a` be the lesser type.
-  if (unsigned(a) > unsigned(b)) {
+  if (static_cast<unsigned>(a) > static_cast<unsigned>(b)) {
     std::swap(a, b);
   }
   HeapType lubUnshared;
@@ -497,7 +497,7 @@
 
     auto insertNew = [&]() {
       auto ptr = getPtr();
-      TypeID id = uintptr_t(ptr.get()) | 1;
+      TypeID id = reinterpret_cast<uintptr_t>(ptr.get()) | 1;
       assert(id > Type::_last_basic_type);
       typeIDs.insert({*ptr, id});
       constructedTuples.emplace_back(std::move(ptr));
@@ -549,7 +549,7 @@
   }
 
   RecGroup insert(std::unique_ptr<RecGroupInfo>&& info) {
-    RecGroup group{uintptr_t(info.get())};
+    RecGroup group{reinterpret_cast<uintptr_t>(info.get())};
     auto canonical = insert(group);
     if (canonical == group) {
       builtGroups.emplace_back(std::move(info));
@@ -919,7 +919,7 @@
   }
   HeapTypeInfo* super = getHeapTypeInfo(*this)->supertype;
   if (super != nullptr) {
-    return HeapType(uintptr_t(super));
+    return HeapType(reinterpret_cast<uintptr_t>(super));
   }
   return {};
 }
@@ -978,7 +978,7 @@
     return std::nullopt;
   }
   if (auto* desc = getHeapTypeInfo(*this)->descriptor) {
-    return HeapType(uintptr_t(desc));
+    return HeapType(reinterpret_cast<uintptr_t>(desc));
   }
   return std::nullopt;
 }
@@ -988,7 +988,7 @@
     return std::nullopt;
   }
   if (auto* desc = getHeapTypeInfo(*this)->described) {
-    return HeapType(uintptr_t(desc));
+    return HeapType(reinterpret_cast<uintptr_t>(desc));
   }
   return std::nullopt;
 }
@@ -1028,7 +1028,7 @@
         case HeapType::noext:
         case HeapType::noexn:
           // Bottom types are infinitely deep.
-          depth = size_t(-1l);
+          depth = static_cast<size_t>(-1l);
       }
       break;
     case HeapTypeKind::Func:
@@ -1218,13 +1218,13 @@
     }
     if (nextA) {
       if (!seen.insert(nextA).second) {
-        return HeapType(uintptr_t(nextA));
+        return HeapType(reinterpret_cast<uintptr_t>(nextA));
       }
       infoA = nextA;
     }
     if (nextB) {
       if (!seen.insert(nextB).second) {
-        return HeapType(uintptr_t(nextB));
+        return HeapType(reinterpret_cast<uintptr_t>(nextB));
       }
       infoB = nextB;
     }
@@ -1240,11 +1240,11 @@
 RecGroup HeapType::getRecGroup() const {
   assert(!isBasic());
   if (auto* info = getHeapTypeInfo(*this)->recGroup) {
-    return RecGroup(uintptr_t(info));
+    return RecGroup(reinterpret_cast<uintptr_t>(info));
   } else {
     // Mark the low bit to signify that this is a trivial recursion group and
     // points to a heap type info rather than a vector of heap types.
-    return RecGroup(id | 1);
+    return RecGroup(getID() | 1);
   }
 }
 
@@ -1350,20 +1350,20 @@
 }
 
 HeapType RecGroup::Iterator::operator*() const {
-  if (parent->id & 1) {
+  if (parent->getID() & 1) {
     // This is a trivial recursion group. Mask off the low bit to recover the
     // single HeapType.
-    return {HeapType(parent->id & ~(uintptr_t)1)};
+    return HeapType(parent->getID() & ~static_cast<uintptr_t>(1));
   } else {
-    return (*(std::vector<HeapType>*)parent->id)[index];
+    return (*reinterpret_cast<std::vector<HeapType>*>(parent->getID()))[index];
   }
 }
 
 size_t RecGroup::size() const {
-  if (id & 1) {
+  if (getID() & 1) {
     return 1;
   } else {
-    return ((std::vector<HeapType>*)id)->size();
+    return reinterpret_cast<std::vector<HeapType>*>(getID())->size();
   }
 }
 
@@ -2004,15 +2004,15 @@
   size_t digest = wasm::hash(bool(info.supertype));
   wasm::rehash(digest, !!info.supertype);
   if (info.supertype) {
-    hash_combine(digest, hash(HeapType(uintptr_t(info.supertype))));
+    hash_combine(digest, hash(HeapType(reinterpret_cast<uintptr_t>(info.supertype))));
   }
   wasm::rehash(digest, !!info.descriptor);
   if (info.descriptor) {
-    hash_combine(digest, hash(HeapType(uintptr_t(info.descriptor))));
+    hash_combine(digest, hash(HeapType(reinterpret_cast<uintptr_t>(info.descriptor))));
   }
   wasm::rehash(digest, !!info.described);
   if (info.described) {
-    hash_combine(digest, hash(HeapType(uintptr_t(info.described))));
+    hash_combine(digest, hash(HeapType(reinterpret_cast<uintptr_t>(info.described))));
   }
   wasm::rehash(digest, info.isOpen);
   wasm::rehash(digest, info.share);
@@ -2139,8 +2139,8 @@
     return false;
   }
   if (a.supertype) {
-    HeapType superA(uintptr_t(a.supertype));
-    HeapType superB(uintptr_t(b.supertype));
+    HeapType superA(reinterpret_cast<uintptr_t>(a.supertype));
+    HeapType superB(reinterpret_cast<uintptr_t>(b.supertype));
     if (!eq(superA, superB)) {
       return false;
     }
@@ -2149,8 +2149,8 @@
     return false;
   }
   if (a.descriptor) {
-    HeapType descA(uintptr_t(a.descriptor));
-    HeapType descB(uintptr_t(b.descriptor));
+    HeapType descA(reinterpret_cast<uintptr_t>(a.descriptor));
+    HeapType descB(reinterpret_cast<uintptr_t>(b.descriptor));
     if (!eq(descA, descB)) {
       return false;
     }
@@ -2159,8 +2159,8 @@
     return false;
   }
   if (a.described) {
-    HeapType descA(uintptr_t(a.described));
-    HeapType descB(uintptr_t(b.described));
+    HeapType descA(reinterpret_cast<uintptr_t>(a.described));
+    HeapType descB(reinterpret_cast<uintptr_t>(b.described));
     if (!eq(descA, descB)) {
       return false;
     }
@@ -2373,7 +2373,7 @@
     info->recGroupIndex = i;
   }
   impl->recGroups.insert(
-    {RecGroup(uintptr_t(groupInfo.get())), std::move(groupInfo)});
+    {RecGroup(reinterpret_cast<uintptr_t>(groupInfo.get())), std::move(groupInfo)});
 }
 
 void TypeBuilder::setOpen(size_t i, bool open) {
@@ -2512,7 +2512,7 @@
   if (auto* super = info.supertype) {
     // The supertype must be canonical (i.e. defined in a previous rec group)
     // or have already been defined in this rec group.
-    if (super->isTemp && !seenTypes.count(HeapType(uintptr_t(super)))) {
+    if (super->isTemp && !seenTypes.count(HeapType(reinterpret_cast<uintptr_t>(super)))) {
       return TypeBuilder::ErrorReason::ForwardSupertypeReference;
     }
     // The supertype must have a valid structure.
@@ -2528,7 +2528,7 @@
       return TypeBuilder::ErrorReason::NonStructDescribes;
     }
     assert(desc->isTemp && "unexpected canonical described type");
-    if (!seenTypes.count(HeapType(uintptr_t(desc)))) {
+    if (!seenTypes.count(HeapType(reinterpret_cast<uintptr_t>(desc)))) {
       return TypeBuilder::ErrorReason::ForwardDescribesReference;
     }
     if (desc->descriptor != &info) {
@@ -2620,7 +2620,7 @@
 
   // Update the supertype.
   if (info->supertype) {
-    HeapType super(uintptr_t(info->supertype));
+    HeapType super(reinterpret_cast<uintptr_t>(info->supertype));
     if (auto it = canonicalized.find(super); it != canonicalized.end()) {
       info->supertype = getHeapTypeInfo(it->second);
     }
@@ -2628,13 +2628,13 @@
 
   // Update the descriptor and described types.
   if (info->descriptor) {
-    HeapType desc(uintptr_t(info->descriptor));
+    HeapType desc(reinterpret_cast<uintptr_t>(info->descriptor));
     if (auto it = canonicalized.find(desc); it != canonicalized.end()) {
       info->descriptor = getHeapTypeInfo(it->second);
     }
   }
   if (info->described) {
-    HeapType desc(uintptr_t(info->described));
+    HeapType desc(reinterpret_cast<uintptr_t>(info->described));
     if (auto it = canonicalized.find(desc); it != canonicalized.end()) {
       info->described = getHeapTypeInfo(it->second);
     }
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 2b1c6cf..b9218e5 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -388,7 +388,7 @@
     if (curr->is<Try>()) {
       self->pushTask(doVisitTry, currp);
       auto& list = curr->cast<Try>()->catchBodies;
-      for (int i = int(list.size()) - 1; i >= 0; i--) {
+      for (int i = static_cast<int>(list.size()) - 1; i >= 0; i--) {
         self->pushTask(scan, &list[i]);
       }
       self->pushTask(visitPreCatch, currp);
@@ -1762,11 +1762,11 @@
       break;
     case Type::f64:
       shouldBeEqual(
-        bytes, uint8_t(8), curr, "expected f64 operation to touch 8 bytes");
+        bytes, static_cast<uint8_t>(8), curr, "expected f64 operation to touch 8 bytes");
       break;
     case Type::v128:
       shouldBeEqual(
-        bytes, uint8_t(16), curr, "expected v128 operation to touch 16 bytes");
+        bytes, static_cast<uint8_t>(16), curr, "expected v128 operation to touch 16 bytes");
       break;
     case Type::unreachable:
       break;
@@ -4282,7 +4282,7 @@
     // resume_throw_ref
     Type exnref = Type(HeapType::exn, Nullable);
     if (shouldBeEqual(curr->operands.size(),
-                      size_t(1),
+                      static_cast<size_t>(1),
                       curr,
                       "resume_throw_ref must have a single exnref operand")) {
       shouldBeSubType(curr->operands[0]->type,
@@ -4419,7 +4419,7 @@
   size_t align, Type type, Index bytes, bool isAtomic, Expression* curr) {
   if (isAtomic) {
     shouldBeEqual(align,
-                  (size_t)bytes,
+                  static_cast<size_t>(bytes),
                   curr,
                   "atomic accesses must have natural alignment");
     return;
@@ -4729,7 +4729,7 @@
         segment->offset,
         "nonzero segment flags require bulk memory [--enable-bulk-memory]");
       info.shouldBeEqual(segment->offset,
-                         (Expression*)nullptr,
+                         static_cast<Expression*>(nullptr),
                          segment->offset,
                          "passive segment should not have an offset");
     } else {
diff --git a/src/wasm2js.h b/src/wasm2js.h
index 3e6c0e0..f82583d 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -247,15 +247,15 @@
 
     // First up check our cached of mangled names to avoid doing extra work
     // below
-    auto& map = wasmNameToMangledName[(int)scope];
+    auto& map = wasmNameToMangledName[static_cast<int>(scope)];
     auto it = map.find(name.str.data());
     if (it != map.end()) {
       return it->second;
     }
     // The mangled names in our scope.
-    auto& scopeMangledNames = mangledNames[(int)scope];
+    auto& scopeMangledNames = mangledNames[static_cast<int>(scope)];
     // In some cases (see below) we need to also check the Top scope.
-    auto& topMangledNames = mangledNames[int(NameScope::Top)];
+    auto& topMangledNames = mangledNames[static_cast<int>(NameScope::Top)];
 
     // This is the first time we've seen the `name` and `scope` pair. Generate a
     // globally unique name based on `name` and then register that in our cache
@@ -311,9 +311,9 @@
   // Mangled names cache by interned names.
   // Utilizes the usually reused underlying cstring's pointer as the key.
   std::unordered_map<const void*, IString>
-    wasmNameToMangledName[(int)NameScope::Max];
+    wasmNameToMangledName[static_cast<int>(NameScope::Max)];
   // Set of all mangled names in each scope.
-  std::unordered_set<IString> mangledNames[(int)NameScope::Max];
+  std::unordered_set<IString> mangledNames[static_cast<int>(NameScope::Max)];
   std::unordered_set<IString> seenModuleImports;
 
   // If a function is callable from outside, we'll need to cast the inputs
@@ -1582,8 +1582,8 @@
         // functions, so we do a bit of a hack here to get our one `Ref` to look
         // like two function arguments.
         case Type::i64: {
-          auto lo = (unsigned)curr->value.geti64();
-          auto hi = (unsigned)(curr->value.geti64() >> 32);
+          auto lo = static_cast<uint32_t>(curr->value.geti64());
+          auto hi = static_cast<uint32_t>(curr->value.geti64() >> 32);
           std::ostringstream out;
           out << lo << "," << hi;
           std::string os = out.str();
@@ -1593,7 +1593,7 @@
         case Type::f32: {
           Ref ret = ValueBuilder::makeCall(MATH_FROUND);
           Const fake;
-          fake.value = Literal(double(curr->value.getf32()));
+          fake.value = Literal(static_cast<double>(curr->value.getf32()));
           fake.type = Type::f64;
           ret[2]->push_back(visitConst(&fake));
           return ret;
@@ -1610,6 +1610,7 @@
         }
         default:
           Fatal() << "unknown const type";
+          WASM_UNREACHABLE("unknown const type");
       }
     }
 
@@ -1786,6 +1787,7 @@
         }
         default: {
           Fatal() << "Unhandled type in unary: " << *curr;
+          WASM_UNREACHABLE("unhandled type");
         }
       }
     }
@@ -2914,6 +2916,7 @@
                "']['" + importedGlobal->base.toString() + "']";
       }
       Fatal() << "non-constant offsets aren't supported yet\n";
+      WASM_UNREACHABLE("unsupported offset");
     };
 
     out << "function initActiveSegments(imports) {\n";